-
-
Notifications
You must be signed in to change notification settings - Fork 80.3k
Bug: fitCodexProjectedContextForTurnStart returns text exceeding maxChars when header + user request fill the turn limit (overflows Codex turn/start) #94748
Copy link
Copy link
Closed
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.ClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.no-staleExclude from stale automationExclude from stale automation
Description
Metadata
Metadata
Assignees
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.ClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.no-staleExclude from stale automationExclude from stale automation
Type
Fields
No fields configured for issues without a type.
Summary
fitCodexProjectedContextForTurnStart(extensions/codex/src/app-server/context-engine-projection.ts:121) can return prompt text longer thanmaxChars, breaking its own contract.The doc-comment (
:120) states it "Fits projected context prompts under Codex app-server turn/start text limits", and the committed test assertsfitted.length <= 420(context-engine-projection.test.ts:221). The overflow path violates both. Onmain@b306745f:When
beforeContext.length + afterContext.length > maxChars,contextBudgetis non-positive,truncateOlderContextreturns""(:447, themaxChars <= 0guard), and the function returnsbeforeContext + "" + afterContext. The older context is silently dropped and the output still exceedsmaxChars.afterContextis\n</conversation_context>\n\nCurrent user request:\n${prompt}— the raw, unbounded user request — so this is reachable with ordinary large input, not a synthetic edge case.Impact
Confirmed by running the actual code (verbatim copies of the three functions at
b306745f):maxCharsbefore + afterfitted.length<= maxChars?Trigger: any turn where the context header plus the trailing user request already fill the limit (a large pasted request, or a small-model context budget where
maxCharsis low). The over-limit text is then handed to the Codex app-server, which hard-rejects the turn:MAX_USER_INPUT_TEXT_CHARS = 1 << 20(openai/codexcodex-rs/protocol/src/user_input.rs), enforced in the v2 turn/start + turn/steer path (codex-rs/app-server/src/request_processors/turn_processor.rs) withInput exceeds the maximum length of {N} characters.So instead of degrading gracefully, the projection emits input that Codex refuses — and below 1MB for small-model budgets the turn also carries less context than intended.Proposed fix
In the
contextBudget <= 0branch, bound the remaining non-context text instead of returning it unbounded. Reuse the existingtruncateOlderContexthelper onbeforeContext + afterContext: it keeps the tail, so the user's actual request survives while the older header text is truncated with the existing marker. Guaranteesoutput.length <= maxCharsin all cases; the happy path (contextBudget > 0) is unchanged. A branch is ready with regression tests for the small-cap and default-1<<20cases (both reproduce the overflow before the fix).Severity: Medium — needs a large prompt or a small-model
maxCharsbudget to trigger; common in long-context / paste-heavy Codex turns, but not every turn.Introduced by #94093 (
fitCodexProjectedContextForTurnStartadded 2026-06-18).