openai / openai/codex

Successful subagent completion messages bypass the completion-context token limit

Open
#40,526 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug context subagent
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What issue are you seeing?
Component and source

Codex core multi-agent V1 and V2 on current main:

  • Commit: cbfd999db78cb088d2bd89b52051efe6f44555a4
  • Component: codex-rs/core and codex-rs/protocol
  • Platform/model/subscription: independent; the problem occurs before the parent model request is constructed
Actual behavior

Successful subagent completion messages are forwarded into the parent agent's model-visible context without any size limit.

Codex defines a 1,000-token completion-message budget in session_prefix.rs. However, only errored completions are truncated. AgentStatus::Completed(Some(message)) clones the entire final message unchanged:

In MultiAgent V2, this unbounded string is placed in InterAgentCommunication and delivered to the parent:

It is then copied unchanged into a model-visible ResponseItem::AgentMessage:

ContextManager::process_item truncates function and custom-tool outputs, but explicitly clones AgentMessage unchanged:

The legacy MultiAgent V1 path has the same problem because it serializes the complete AgentStatus into a SubagentNotification:

Impact

A subagent returning a sufficiently large final answer can inject a single item larger than the intended completion budget, and potentially larger than the parent's remaining context window. This can cause excessive context growth, premature compaction, or context_length_exceeded on the parent's next request.

The existing test covers truncation of errored completions only:

What steps can reproduce the bug?

This can be reproduced deterministically with a regression test beside the existing error-completion test:

#[test]
fn successful_completion_message_stays_below_completion_budget() {
    let message = format_inter_agent_completion_message(
        AgentPath::root(),
        AgentPath::try_from("/root/worker").expect("valid agent path"),
        &AgentStatus::Completed(Some("large subagent result ".repeat(20_000))),
    )
    .expect("completed status should produce a completion message");

    assert!(
        approx_token_count(&message) < COMPLETION_MESSAGE_MAX_TOKENS,
        "successful completion contained {} tokens",
        approx_token_count(&message),
    );
}

The assertion currently fails because the complete successful result is returned unchanged.

A higher-level reproduction is:

  1. Start a parent task with multi-agent support enabled.
  2. Spawn a child agent whose final response exceeds 10,000 tokens.
  3. Wait for the child to complete.
  4. Inspect the parent's next model request or normalized conversation history.
  5. Observe that the entire child result is present in a single AgentMessage without truncation or spill handling.
What is the expected behavior?

All model-visible subagent completion messages should have a hard size limit.

At minimum:

  • Successful completions should honor COMPLETION_MESSAGE_MAX_TOKENS, just as error completions do.
  • The same limit should apply consistently to MultiAgent V1 and V2.
  • Truncated messages should contain an explicit marker explaining that content was omitted.
  • If the full result must remain accessible, the bounded parent message should reference the child thread or a stored artifact instead of embedding the entire result.
  • Integration coverage should verify that the actual message delivered to the parent remains bounded.
Additional information

This is related to the broader context-hygiene concern in #40493, which mentions bounding successful subagent completion forwarding.

This report is intentionally narrower and provides a deterministic source-level reproduction: a single successful completion bypasses the explicit 1,000-token completion-message budget. It does not depend on cumulative tool-output growth or recursive session-state reads.

A possible fix is to truncate or spill successful completion payloads before constructing either InterAgentCompletionMessage or SubagentNotification, while preserving a bounded reference to the child thread for retrieving the full result.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the existing error-completion test in codex-rs/core/src/session_prefix_tests.rs and the completion budget in codex-rs/core/src/session_prefix.rs. Trace successful completion handling through codex-rs/core/src/session/mod.rs, codex-rs/protocol/src/protocol.rs, and codex-rs/core/src/agent/control.rs, then verify bounded messages for both MultiAgent V1 and V2. Done means successful model-visible completions stay within the budget and include an omission marker, with regression coverage.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
ai-infra-agents
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.