An annotation sent with "Steer" starts as many duplicate Codex turns as there are other VS Code windows with the Codex panel open, causing multiple concurrent writes to the same rollout and workspace
What version of the IDE extension are you using?
openai.chatgpt 26.5727.51351-darwin-arm64
What subscription do you have?
Plus
Which IDE are you using?
VS Code
What platform is your computer?
Darwin 25.6.0 arm64 arm
What issue are you seeing?
This one is tightly related to the other concurrency bug reported in #38629, but the trigger here is different and the impact is higher: a single user action performed in one VS Code window silently starts "background" concurrent turns, one for every other VS Code window with the Codex panel open.
Each duplicate turn then independently tries to write to the same workspace at the same time as the others.
The concrete failure mode is described below.
What steps can reproduce the bug?
- Open one VS Code window with a folder/workspace (window A).
- Open the Codex panel in that window, send
Test. Reply "ANNOTATE_ME" and stop., and wait for the response. - Open a few other, independent VS Code windows. Open the Codex panel in each one, and let the Codex webview load. Opening the same chat that contains
ANNOTATE_MEis not necessary for the reproduction; you may leave the panels in the default state or open other, unrelated chats. - In the initial window A, with the initial
ANNOTATE_MEchat still open, send this prompt to imitate a long-running job:
``text``
Perform 30 sequential cycles: for cycle n, run sleep 5 as a separate terminal command, then send a progress update in this format: TICK n/30. Do not combine cycles into one shell loop. Do not modify any files until I say so. Stop when you reach TICK 30/30.
Wait for at least one TICK n/30 to appear.
- In the same window A, select any text in a previous Codex response, for example,
ANNOTATE_ME, click the annotation bubble ("Add to chat"), and add any annotation. To make the failure more observable without even needing to inspect rollout files, you can use this prompt:
``text``
Pick a random file name <random-name>.txt (don't use one that is solely time-based), create A SINGLE FILE with that name in this workspace root, and, after each TICK, also write TICK n/30 to that file you created. Proceed until TICK 30/30.
Click Send (Ctrl/Cmd+Enter).
- Click
Steeron the just-created pending annotation message.
At this point, the existing Codex app-server instances in the other VS Code windows resume the conversation and start separate turns from the same annotation. The original turn in window A also handles the annotation, so a single instruction to create a single file creates multiple <random-name>.txt files, one per turn, all at almost exactly the same time. Each turn writes its own independent TICK n/30 sequence to its file, and all of the turns write to the same session rollout file simultaneously.
In a real project where this was observed, that led to multiple interleaving edits to the same files, until eventually 3 out of 4 concurrent Codex turns stopped to ask, "Are you editing the files while I do it?"
If you inspect the extension logs and rollout, you may see that the dormant clients resumed the conversation a few milliseconds apart, each became the owner, and the one annotation started a separate turn in each existing app-server process associated with another VS Code window.
- Reproduce the additional failure - the inability to stop:
Click "Stop" in the visible chat - this stops only the visible branch; the hidden turns continue running and writing files. Alternatively, send something like "Fully stop now." in Steer mode. Codex may produce a visible "Stopped." reply and the UI may appear to be in the stopped state, while the hidden turns continue running and writing files.
For a successful repro, it is important to open new VS Code windows when the annotation-testing chat already exists.
What is the expected behavior?
As with #38629, a single conversation must have at most one mutation-capable active turn. A response annotation submitted with Steer should never make unrelated VS Code windows start producing duplicate/concurrent turns in the same conversation.
If a client from another VS Code window is a follower, it must remain a follower unless ownership is transferred explicitly through a single coordinated operation.
The visible Stop control should stop active work in the conversation, and no "invisible" background work should continue if the agent reports that it has stopped and the UI changes to the stopped state.
Additional information
Relevant extension log sequence from a clean three-window reproduction:
``text``
15:36:41.543 window 2 maybe_resume_started; previousResumeState=needs_resume; previousStreamRole=null
15:36:41.544 window 3 maybe_resume_started; previousResumeState=needs_resume; previousStreamRole=null
15:36:42.436 window 2 role=owner
15:36:42.438 window 2 maybe_resume_success; latest timer turn status=interrupted
15:36:42.443 window 3 role=owner
15:36:42.445 window 3 maybe_resume_success; latest timer turn status=interrupted
15:36:57.155 window 2 reasoning activity; turnId=01a03433-c275-76c3-8428-bfbcbbdd793f
15:36:58.501 window 3 reasoning activity; turnId=01a03433-c27d-7df1-bf1d-192ff7ecf81e
After windows 2 and 3 were opened, both clients logged documentVisibilityState=visible, although the marker chat had never been selected there. Ownership then oscillated between the two resumed clients while the original active client became a follower.
Bundled Codex CLI: 0.146.0-alpha.9.2.