codex exec --json emits duplicate id keys for web-search items
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 84/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- backend-api-design, cli, testing
Research direction
Start in codex-rs/exec/src/exec_events.rs, where the issue points to the outer item and flattened web-search payload definitions. Trace how those fields serialize, then add a raw JSON serialization test that rejects duplicate keys, as requested in the issue. Done means each emitted web-search item has one unambiguous id and the test confirms duplicate keys are rejected.
Written by the indexing model from the issue text.
Description
What issue are you seeing?
codex exec --json emits two different id properties in each web-search item. Parsers that keep the first property identify the item as item_1; parsers that keep the last identify it as ws-1. A duplicate-rejecting parser cannot consume the event.
This is separate from #60990, which concerns an omitted TypeScript field.
Reproduction
Run from the repository root with the Python SDK dependencies and codex on PATH. The Responses API is a local mock; no external web request is made.
import json, os, shutil, subprocess, sys, tempfile
from pathlib import Path
sys.path[:0] = [str(Path("sdk/python/src").resolve()),
str(Path("sdk/python/tests").resolve())]
from app_server_harness import (
AppServerHarness, ev_assistant_message, ev_completed,
ev_response_created, sse,
)
def reject_duplicates(pairs):
result = {}
for key, value in pairs:
if key in result:
raise ValueError(f"duplicate key: {key}")
result[key] = value
return result
with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as tmp:
with AppServerHarness(Path(tmp)) as harness:
added = {"type": "response.output_item.added", "item": {
"type": "web_search_call", "id": "ws-1", "status": "in_progress"}}
done = {"type": "response.output_item.done", "item": {
"type": "web_search_call", "id": "ws-1", "status": "completed",
"action": {"type": "search", "query": "example"}}}
harness.responses.enqueue_sse(sse([
ev_response_created("r1"), added, done,
ev_assistant_message("m1", "Finished."), ev_completed("r1"),
]))
env = dict(os.environ, CODEX_HOME=str(harness.codex_home),
CODEX_APP_SERVER_DISABLE_MANAGED_CONFIG="1")
proc = subprocess.run([
shutil.which("codex"), "exec", "--json", "--skip-git-repo-check",
"-c", 'web_search="cached"', "-c", "features.plugins=false",
"-c", "features.plugin_discovery_prefetch=false", "Example",
], cwd=harness.workspace, env=env, capture_output=True, text=True,
check=True, timeout=15)
for line in proc.stdout.splitlines():
event = json.loads(line)
if event.get("item", {}).get("type") == "web_search":
print(line)
try:
json.loads(line, object_pairs_hook=reject_duplicates)
except ValueError as error:
print(error)
Observed for the started item (the completed item has the same duplication):
{"type":"item.started","item":{"id":"item_1","type":"web_search","id":"ws-1","query":"","action":{"type":"other"}}}
duplicate key: id
Python's default decoder retains ws-1; a first-wins decoder retains item_1. A separate structurally equivalent Serde deserialization test returned duplicate field id.
Expected behavior
Emit one unambiguous id per item. The outer item flattens a web-search payload that also has an id. Remove the duplicate or give the raw search identifier a distinct field name if both IDs are needed. Add a raw-JSON serialization test that rejects duplicate keys.
Tested with Codex CLI 0.167.0-alpha.4.1, Python 3.14.0, and Windows; source checked at 6bfdc75f0d9e6fae313234f694839866d7c63c39.
- Dominant language
- Rust
- Stars
- 135k
- Forks
- 21.4k
- Avg merge
- 1m
- Merged PRs (30d)
- 995
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openai/codex
-
bug CLI exec session
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
bug CLI config
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
app-server bug CLI
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
bug CLI exec windows-os
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
app-server bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
Similar issues
-
compatibility
Difficulty 1/5 Under an hour Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
aws/aws-emulator#30 · 1 comment ·
-
tormach-plasma refusal text with no machine reads "no machine is not declared a plasma machine"Openarea:post bug effort:low P2 source:agent
Difficulty 1/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
Higher Interval Candles draws nothing on a seconds chart whose interval does not divide two hoursOpenbug studies
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
userFRM/egui-charts#2727 ·
Maintainers usually reply within 1 day
-
enhancement priority::low upstream
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
Maintainers usually reply within 1 day