ZhuLinsen/daily_stock_analysis · error · CodexAppServerError
resource_limit_exceeded
resource_limit_exceeded
Error message
App Server exceeded the cumulative item budget
What it means
run_turn() enforces MAX_TURN_ITEM_COUNT (1024) on the cumulative items returned by turn/completed. If the app-server accumulates more items than this budget (extra items are also tracked per notification in the reader thread), it raises code 'resource_limit_exceeded' with turn_started=True to bound memory and transcript size.
Source
Thrown at src/agent/codex_app_server_transport.py:519
notification = self._wait_for_turn(
thread_id,
turn_id,
self.request_timeout if timeout is None else timeout,
cancel_event=cancel_event,
)
except CodexAppServerError as exc:
raise CodexAppServerError(exc.code, str(exc), turn_started=True) from exc
completed_turn = notification.get("params", {}).get("turn") or {}
status = str(completed_turn.get("status", "unknown"))
terminal_items = completed_turn.get("items", [])
if not isinstance(terminal_items, list):
raise CodexAppServerError(
"protocol_error",
"turn/completed returned a non-list items field",
turn_started=True,
)
if len(terminal_items) > MAX_TURN_ITEM_COUNT:
raise CodexAppServerError(
"resource_limit_exceeded",
"App Server exceeded the cumulative item budget",
turn_started=True,
)
if status != "completed":
error = completed_turn.get("error") or {}
info = error.get("codexErrorInfo")
if status == "interrupted":
code = "cancelled"
else:
normalized_info = str(info or "").strip().casefold()
code = "login_required" if normalized_info == "unauthorized" else "unknown_backend_error"
message = redact_diagnostic_value(
error.get("message", f"Turn ended with status {status}"),
limit=500,
)
raise CodexAppServerError(code, message, turn_started=True)
with self._state_lock:View on GitHub (pinned to 5159bd72e8)
Solutions
- Lower request.max_steps / max_tool_calls so the turn is cut off by step budget before item count explodes
- Tighten the agent prompt to require convergence and cap repeated tool calls for the same goal
- Check whether a specific tool's error output is triggering model retry loops and fix that tool's contract
- If genuinely needed, negotiate a higher MAX_TURN_ITEM_COUNT — but treat 1024+ items in one turn as a design smell first
Example fix
# before request = AgentRequest(..., max_steps=200) # model can emit 1000+ tool items # after request = AgentRequest(..., max_steps=24) # converge before the 1024-item budget
Defensive patterns
Strategy: validation
Validate before calling
if request.max_steps * ESTIMATED_ITEMS_PER_STEP > MAX_TURN_ITEM_COUNT:
request = replace(request, max_steps=MAX_TURN_ITEM_COUNT // ESTIMATED_ITEMS_PER_STEP)
# and fail fast if remaining budget cannot fit a converging turn Type guard
def within_item_budget(item_count: int, limit: int = 1024) -> bool:
return item_count <= limit Try / catch
try:
turn = client.run_turn(thread_id, text, timeout=t)
except CodexAppServerError as exc:
if exc.code == "resource_limit_exceeded":
return AnalysisOutcome.diverged("turn exceeded item budget; tighten max_steps and prompts")
raise Prevention
- Set max_steps/max_tool_calls low enough that items cannot approach 1024
- Prompt for convergence; forbid repeated identical tool calls
- Watch item counts per turn in metrics to catch divergence trends early
When it happens
Trigger: A runaway agent loop where the model calls tools repeatedly without converging, producing >1024 items in one turn; a server bug duplicating items in the completion payload; prompts that encourage excessive step-by-step decomposition within a single turn.
Common situations: Analysis tasks with unbounded tool loops (e.g. the model keeps requesting data with slightly different parameters); a tool that returns errors causing infinite retry behavior by the model; raising the budget-sensitive workload without tuning prompts or max_tool_calls.
Related errors
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/b6668d2cf7fd62f5.
Report an issue: GitHub.