Skip to content

Subagent quota exhaustion is surfaced as “no response” instead of an explicit failure status to the main agent #16891

Open

Description

@hyophyop

What version of the Codex App are you using (From “About Codex” dialog)?

26.325.31654(1272)

What subscription do you have?

ChatGPT Pro

What platform is your computer?

No response

What issue are you seeing?

When the main agent delegates work to a subagent, the two agents may be configured to use different models.

In this setup, if the subagent model has exhausted its usage/quota, the subagent should fail with an explicit status indicating that it could not run because the model quota was exhausted.

Instead, the main agent appears to receive this as a generic “no response” outcome. That loses the real failure reason and makes it look like the subagent silently failed or returned nothing, rather than failing due to model usage exhaustion.

This is problematic because:

  • the main agent cannot distinguish quota exhaustion from other execution failures
  • the main agent cannot react appropriately (retry with another model, degrade gracefully, report a clear error, etc.)
  • debugging multi-agent runs becomes harder because the causal failure is hidden

Expected behavior is that subagent quota exhaustion should propagate to the main agent as a structured, explicit failure state rather than collapsing into “no response”.

What steps can reproduce the bug?

  1. Configure a workflow where the main agent delegates a task to a subagent.
  2. Use a different model for the subagent than for the main agent.
  3. Ensure the subagent model is at or beyond its usage limit / quota.
  4. Trigger a task that requires the subagent to run.
  5. Observe the result shown to the main agent.

Observed result:

  • the main agent treats the subagent as having produced no response
  • the actual reason, that the subagent could not run because its model quota was exhausted, is not surfaced as an explicit status

Expected result:

  • the subagent should return a clear failure status such as quota exhausted / usage limit reached / model unavailable due to quota
  • the main agent should receive that status explicitly instead of a generic no-response outcome
  • ideally the main agent can use that status for fallback or user-facing error reporting

Notes:

  • This seems specifically related to subagent-to-main-agent error propagation across different model assignments
  • The issue is not merely that the subagent fails; the issue is that the failure reason is lost

What is the expected behavior?

If a subagent cannot execute because the assigned model has exhausted its usage limit, that condition should be propagated to the main agent as an explicit, structured failure state.

The main agent should be able to distinguish at least these cases:

  • subagent completed successfully
  • subagent failed due to quota / usage exhaustion
  • subagent failed due to timeout
  • subagent failed due to transport / internal error
  • subagent produced an empty result intentionally

A quota exhaustion case should not be collapsed into a generic “no response”.

Additional information

This looks like an error-classification / status-propagation bug in the multi-agent execution path.

From an orchestration perspective, “subagent did not respond” and “subagent could not run because its model quota was exhausted” are materially different states and should not be conflated.

A structured failure payload would allow the main agent to:

  • retry with another model
  • skip the subagent and continue with degraded behavior
  • report an accurate reason to the user
  • make debugging and telemetry much clearer

Activity

  1. added
    appIssues related to the Codex desktop app
    on Apr 6, 2026
  2. added
    bugSomething isn't working
    rate-limitsIssues related to rate limits, quotas, and token usage reporting
    on Apr 6, 2026
  3. added
    agentIssues related to the core agent loop
    subagentIssues involving subagents or multi-agent features
    and removed
    appIssues related to the Codex desktop app
    agentIssues related to the core agent loop
    on Apr 6, 2026
  4. starSumi commented on Aug 20, 2026

    @starSumi

    Current main appears to have fixed the empty-completion symptom in #28375, but it still discards machine-readable error metadata at the parent/child boundary.

    Environment and evidence

    • Windows 11, codex-cli 0.147.0, MultiAgentV2 children used during an active Goal, with custom Responses-compatible providers.
    • One rollout contained 13 terminal child notifications for provider responses equivalent to 403 Forbidden: insufficient balance, from two provider origins.
    • Every child notification reached the parent only as {"errored":"<message>"}. A structured scan found 11 later followup_task calls targeting 7 of the 13 errored child paths; the other 6 paths were not redispatched. Those were explicit parent/model tool calls, not automatic runtime retries. This trace shows that an errored resident child can be redispatched after the parent receives display text, while the runtime provides no typed class for retry policy.
    • The same provider failure class was recorded on root turn errors as codex_error_info: "other", even though the HTTP status was present in the human-readable message.

    Current source path

    • ErrorEvent already carries both message and codex_error_info.
    • Core error conversion already maps native usage-limit and quota errors to CodexErrorInfo::UsageLimitExceeded, and can recover the HTTP status from UnexpectedStatus (conversion).
    • Terminal child forwarding takes an ErrorEvent but reduces it to AgentStatus::Errored(error.message) (forwarding path); the protocol variant itself remains string-only (status type).

    Narrow request

    Please preserve the existing ErrorEvent.codex_error_info when a terminal child error is forwarded, and preserve an optional HTTP status for an UnexpectedStatus failure rather than reducing it to an untyped string. The display message can remain for diagnostics.

    That would let a parent or Goal supervisor apply policy only after it has a machine-readable class and scope. It would also avoid treating every 403 or 429 as quota exhaustion: this reproduction used custom providers, and their status semantics are provider-specific. This evidence does not support unconditional sibling cancellation or automatic replay.

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

    bugSomething isn't workingrate-limitsIssues related to rate limits, quotas, and token usage reportingsubagentIssues involving subagents or multi-agent features

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions