Skip to content

[Bug]: Codex turns started by T3 end early on long multi-step tasks; the same model finishes as a native Codex subagent or via codex exec #32488

Closed

Description

@super148666

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. In T3 Code, start a Codex thread, or a delegate_task child, with gpt-6.1-terra and reasoningEffort: medium.
  2. Give it a long multi-step file task. My test task was: read a short brief and a vocabulary file, then process 9 text chunks (201 records) one at a time. For each chunk, print it, decide labels, and append JSONL rows to an output file. Finish with a check script. The prompt says explicitly: "This is a long task; there is no time limit. Do not end your turn until both output files exist and the final check passes."
  3. Check the output files when the turn ends.

Control runs, using the identical task text, the same model and effort, the same machine and the same ~/.codex config:

  • A. From a T3 Codex thread, have the agent start the child with Codex's native spawn_agent (gpt-6.1-terra, effort medium).
  • B. Run codex exec -m gpt-6.1-terra -c model_reasoning_effort=medium directly, without T3.

Expected behavior

The turn continues until the task is finished, as it does in control runs A and B.

Actual behavior

When T3 starts the Codex turn, the agent usually ends its turn after setup or after one chunk. Its final message honestly says the work is incomplete, for example "processed chunk 01 only; chunks 02–09 remain outstanding". Sending "continue" once or twice then lets it finish.

The table shows whether the whole task was done in the first turn (gpt-6.1-terra, effort medium, identical task):

How the turn was started Full task done in first turn
T3 delegate_task child (parent was Claude or Codex) 0/7 (stopped at 0–25 of 201 records)
T3 top-level Codex thread 0/4
Native Codex spawn_agent child, inside a T3 Codex thread 3/3
codex exec (no T3) 2/2

Other runs through T3 on the same task:

Model and effort Full task done in first turn
terra high 0/2
terra low 1/1
terra xhigh 2/2
gpt-6.1-sol medium 1/1
gpt-6-luna high 0/2

The samples are small, but the split by launch path is consistent.

What I found in the Codex session rollouts and the T3 provider log:

  • The codex exec session also runs as /root and loads the same global ~/.codex/AGENTS.md. Neither the root role nor that file explains the difference.
  • In T3-started turns, turn/start sends collaborationMode.settings.developer_instructions with the full "# Collaboration Mode: Default ..." text. In the codex exec session and in the native spawn_agent child, turn_context.collaboration_mode.settings.developer_instructions is null.
  • T3-started turns also add additionalContext blocks: t3_code_orchestration_01..03, t3_code_runtime (runtime info and PR linking) and t3_code_tools. These are absent in both control runs.

I have not yet tested which of these two additions triggers the early stop.

Adding a "keep working toward the goal until done" instruction to the task text did not help in one T3 run: it stopped after 25 of 201 records.

Impact

Major degradation or frequent failure. Long delegated Codex tasks silently return partial work, and the parent has to verify the output and resend "continue". It looks like a model problem, but the same model completes the task when it is launched outside T3's turn path.

Version or commit

T3 Code (Nightly) desktop 0.1.8.0

Environment

Windows 11 Pro (10.0.26200). codex-cli 0.167.0, through T3's Codex app-server provider. Model gpt-6.1-terra, reasoningEffort: medium.

Logs or stack traces

From the T3 provider event log, turn/start payload (trimmed):

"collaborationMode":{"mode":"default","settings":{"model":"gpt-6.1-terra","reasoning_effort":"...","developer_instructions":"# Collaboration Mode: Default\r\n\r\nYou are now in Default mode. ..."}},
"additionalContext":{"t3_code_orchestration_01":{"kind":"application","value":"## T3 Code orchestration ..."}, ...}

Rollout turn_context for each launch path:

T3 delegate_task child : collaboration_mode.settings.developer_instructions = "# Collaboration Mode: Default ..."
native spawn_agent     : collaboration_mode.settings.developer_instructions = null
codex exec             : collaboration_mode.settings.developer_instructions = null

Workaround

  • Have a Codex thread start the work as a native spawn_agent child instead of using delegate_task, or run codex exec.
  • Use gpt-6.1-sol, or terra at xhigh.
  • Verify the outputs independently and send "continue" when the child stops early.

Related upstream reports of the same symptom, mostly from Codex Desktop, which is also an app-server client: openai/codex#50771, openai/codex#57843, openai/codex#46153.

Activity

  1. juliusmarminge commented on Nov 7, 2026

    @juliusmarminge
    Member

    Thanks for the detailed report and the rollout comparison. I could not reproduce the early stop on current main (e455200), Linux, codex-cli 0.163.0 and 0.167.0.

    Task. A synthetic version of yours: BRIEF.md, a 7-label vocabulary.md, 9 chunk files with 201 records, and a check.py. The brief says to process chunks one at a time, cat each one, label by hand, append JSONL rows, then write out/summary.json. The prompt ends with your sentence: "This is a long task; there is no time limit. Do not end your turn until both output files exist and the final check passes."

    What I ran (full task done in the first turn):

    Launch path Model / effort Result
    T3 dev server, top-level Codex thread gpt-6.1-terra / default 1/1
    T3 dev server, delegate_task child (Codex parent) gpt-6.1-terra / medium 1/1
    codex app-server turn/start shaped exactly like T3's (collaborationMode: default + T3 additionalContext) terra medium 3/3 (0.163.0), 3/3 (0.167.0)
    same, without either addition (like codex exec) terra medium 3/3 (0.163.0), 3/3 (0.167.0)
    same, only additionalContext / only collaborationMode terra medium 3/3 / 3/3
    T3-shaped vs bare terra high 3/3 vs 3/3
    T3-shaped vs bare gpt-6-luna high 2/2 vs 2/2

    The rollout difference you describe shows up here too. T3-shaped turns record collaboration_mode.settings.developer_instructions = "# Collaboration Mode: Default ...", and the bare turns record null. On this task it made no difference to whether the turn finished.

    To narrow this down, could you share:

    1. A task that still stops early for you: the exact prompt plus the brief, vocabulary and a couple of chunks, or a synthetic stand-in that you have seen stop. Our records are one short line each; if yours are much longer, that matters.
    2. For one T3 run that stopped early, the Codex rollout JSONL for that thread (redacted as needed), at least from the last tool call to the end of the turn, plus the T3 provider event log lines around that turn's turn/completed (its status, and any compaction or steer events just before it).
    3. How the parent in the delegate_task runs was set up: its provider and model, and the exact delegate_task call (task text, target, mode).
  2. super148666 commented on Nov 7, 2026

    @super148666
    Author

    Update and correction after more isolation work. I reproduced this outside T3, so it is probably not a T3 bug.

    Correction: the codex exec session also receives the same <collaboration_mode># Collaboration Mode: Default text. developer_instructions: null in turn_context means "use the built-in text", not "no text". So that difference was wrong.

    Reproduction without T3: I wrote a minimal stdio client for codex app-server. It replays T3's captured initialize, thread/start config and turn/start params exactly, apart from cwd and output dir and without the authenticated T3 MCP servers. Model gpt-6.1-terra, effort medium. This tests whether the whole task (9 chunks) is done in the first turn:

    Variant Full task done in first turn
    exact replay of T3's requests 0/3
    without additionalContext (no T3 blocks) 0/2
    without tools.update_plan.enabled 0/2
    summary: auto instead of detailed 0/2
    approvalsReviewer: auto_review 0/2
    all four of the above removed together 0/2
    clientInfo.name changed from "T3 Code" 0/2
    without collaborationMode / without effort / without sandboxPolicy+approvalPolicy (one at a time) 0/2 each
    codex exec with the same prompt plus T3's five context blocks as developer_instructions 3/3
    codex exec, plain 2/2
    native spawn_agent child inside an app-server thread 3/3

    None of T3's additions explains the early stop. It follows the launch path: a top-level app-server thread (source: vscode) stops early, while exec and spawn_agent children do not.

    One caveat: a replay that sent only threadId and input completed (4/4). Without sandboxPolicy, though, it fell back to workspace-write with auto-review escalations on almost every command, so that result is confounded.

    I've added these details to the Codex-side report (openai/codex#60133). Feel free to close this one if you agree it is upstream. A practical mitigation on the T3 side, if useful: route long Codex delegations through a native spawn_agent child.

  3. juliusmarminge commented on Nov 7, 2026

    @juliusmarminge
    Member

    Thanks for isolating this. Closing it as an upstream Codex app-server issue, tracked in openai/codex#60133.

    What the evidence shows:

    • Your replay with a bare codex app-server stdio client and no T3 stops early in every variant. That includes removing additionalContext, collaborationMode, effort, sandboxPolicy/approvalPolicy, update_plan, summary, approvalsReviewer and the clientInfo name, one at a time and the first four together.
    • codex exec with T3's five context blocks as developer_instructions completes 3/3. So T3's added context does not cause the stop either.
    • Our earlier runs on main (e455200, Linux, codex-cli 0.163.0 and 0.167.0) finished the synthetic 9-chunk task in the first turn on every path: a T3 top-level Codex thread, a delegate_task child, and app-server turns with or without T3's additions.

    The early stop depends on the app-server launch path, not on anything in T3's requests, so we have nothing to change on our side. If openai/codex#60133 turns up a client-side setting that avoids it, comment here and we'll reopen.

  4. super148666 commented on Nov 7, 2026

    @super148666
    Author

    Update: this stopped reproducing for me on the evening of 2026-11-07, without any local change.

    Time (UTC+8) Exact replay of the client's turn/start (terra medium) Full task done in first turn
    up to 22:47 same script, same task 0/19
    23:43 the real T3 delegate_task path 1/1
    23:48 same replay script, same task 2/2

    Nothing local changed in between:

    • the same codex.exe 0.167.0, binary dated 2026-11-06
    • the same base-instructions hash
    • the same config for the replay
    • the same task

    This points to a server-side change or a time-varying issue, not to anything client-side. I'll report back if it returns. Feel free to close.

    Thank you to the T3 Code maintainers, especially juliusmarminge, for the quick and thorough investigation, the independent repro attempts and the clear triage. It helped a lot in narrowing this down.

  5. super148666 commented on Nov 10, 2026

    @super148666
    Author

    Following up on the reopen condition ("a client-side setting that avoids the stop"): I found one, and the early stops did not actually go away on Nov 7. Full data is in openai/codex#60133 (comment).

    What triggers it

    The turn ends early when the effort T3 sends in turn/start differs from the effort the thread started with. T3's thread/start config does not carry an effort, so the thread starts with model_reasoning_effort from the user's ~/.codex/config.toml. When the two differ, Codex adds a configuration_update item ({"reasoning":{"effort":"..."}}) to the turn, and gpt-6.1-terra and gpt-6-luna then stop after a few tool calls.

    This probably explains why it did not reproduce on your side: your default effort likely matched the effort used in the test. It also explains why it "fixed itself" for me: my config.toml default became medium, which matched the turns I was replaying.

    Controlled runs (Nov 10, codex-cli 0.167.0, Windows 11)

    Replay of T3's own thread/start + turn/start against a bare codex app-server. Only the effort placement changes. My config.toml default is medium.

    Model Effort in thread/start config Effort in turn/start Completed in first turn Seconds
    gpt-6.1-terra not sent (config default medium) medium 2/2 221, 236
    gpt-6.1-terra not sent (config default medium) high 0/2 40, 63
    gpt-6.1-terra model_reasoning_effort: high high 2/2 253, 216
    gpt-6.1-terra model_reasoning_effort: high medium 0/2 39, 37
    gpt-6-luna not sent (config default medium) high 0/2 76, 45
    gpt-6-luna model_reasoning_effort: high high 2/2 508, 496

    All 6 failing runs have the configuration_update item in the rollout; none of the 6 passing runs do. My 21 failing app-server runs from Nov 7 all have it as well.

    Suggested change in T3

    Send model_reasoning_effort in the thread/start config, equal to the effort of the first turn. Rows 3 and 6 show that this avoids the stop for any effort, without the user having to edit config.toml.

    Two cases where this matters most:

    • delegate_task children. When the caller passes no effort, T3 picked low for gpt-6.1-terra while my config default was medium, so the child got the configuration_update item and stopped after 56 seconds.
    • Any thread where the effort chosen in the T3 picker differs from the user's Codex default.

    This does not cover changing effort in the middle of an existing thread; that still needs a fix in Codex. I only tested the first turn of a thread.

  6. super148666 commented on Nov 10, 2026

    @super148666
    Author

    Two additions to my previous comment: where the change would go, and a workaround that works today. Could this be reopened? There is now a client-side setting that avoids the stop.

    Where the effort is dropped

    In the server bundle of T3 Code (Nightly) 0.1.9-nightly.20261110.4465, codexThreadRuntimeParams (Codex adapter v2, next to CODEX_THREAD_CONFIG) builds the thread/start params. It receives input.modelSelection but only forwards the model:

    ...input.modelSelection === void 0 ? {} : { model: input.modelSelection.model },
    config: {
      ...CODEX_THREAD_CONFIG,
      ...
    }

    The reasoningEffort option of the same modelSelection is not put into config, so the thread starts with the user's Codex default and the first turn/start then overrides it. Adding model_reasoning_effort: <selected effort> to that config object when an effort is selected should be enough. In my replays, a thread/start config with model_reasoning_effort equal to the turn effort completed 2/2 for gpt-6.1-terra and 2/2 for gpt-6-luna, against 0/2 each without it.

    Workaround that works now

    The Codex instance setting "Launch arguments" can carry the effort:

    -c model_reasoning_effort="high"
    

    I tested the equivalent directly: codex app-server -c model_reasoning_effort="high", gpt-6.1-terra, turn/start effort high, while config.toml still says medium. It completed 2/2 (195 s and 227 s) with no configuration_update item in the rollout. The same turn without the launch argument ended early 0/2.

    The limit is that one instance covers one effort, so using several efforts needs several instances. That is why a fix in thread/start would still help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions