fix(agents): prevent Codex missing_tool_result from triggering cross-provider model fallback#95520
fix(agents): prevent Codex missing_tool_result from triggering cross-provider model fallback#95520zhangqueping wants to merge 2 commits into
Conversation
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close as superseded: this PR targets the same missing-tool-result fallback bug, but #95543 is open, mergeable, proof-positive, and covers the same central guard with stronger runtime-boundary proof plus provider-metadata precedence coverage. Canonical path: Use #95543 as the canonical landing path, or land an equivalent central guard that preserves provider metadata precedence and proves the runtime fallback boundary. So I’m closing this here and keeping the remaining discussion on #95543. Review detailsBest possible solution: Use #95543 as the canonical landing path, or land an equivalent central guard that preserves provider metadata precedence and proves the runtime fallback boundary. Do we have a high-confidence way to reproduce the issue? Yes at source level: current main synthesizes the Codex missing-tool-result sentinel and the model fallback loop consumes remaining candidates for unclassified errors. I did not run a live hung-shell Codex OAuth scenario in this read-only review. Is this the best way to solve the issue? No for this branch as the best landing path: the central non-provider guard is the right boundary, but #95543 covers the same fix with runtime-loop proof and provider-metadata precedence that this PR lacks. Security review: Security review cleared: The diff changes agent error classification and tests only; no dependency, CI, permission, secret, install, or supply-chain surface changed. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 12c34fc3a951. |
d00d88c to
44f742f
Compare
…provider model fallback - Add hasLocalNativeToolExecutionFailure to detect synthetic missing tool result errors from the Codex harness in failover-error.ts - Extend isNonProviderRuntimeCoordinationError to abort model fallback for local native tool execution failures (no other model can fix them) - Add unit tests for direct, nested (cause), and nested (error property) missing tool result detection Fixes openclaw#95474
f04f563 to
7447268
Compare
|
ClawSweeper applied the proposed close for this PR.
|
Summary
When the Codex harness synthesizes a
missing_tool_resultfor a hung nativebashcall, the error percolates through the failover classification pipeline without matching any known provider-failure pattern. The outerrunWithModelFallbackloop inmodel-fallback.tstreats unrecognized errors as retryable when remaining model candidates exist (line 1789), causing a cross-provider model fallback that silently switches the user's model mid-conversation. No other provider/model can fix a local tool execution failure.This fix adds detection of the Codex
MISSING_TOOL_RESULT_ERRORtext pattern inisNonProviderRuntimeCoordinationError, which is already checked at both the inner runner (line 366) and outer fallback loop (line 1717) inmodel-fallback.ts. When detected, the error is treated as a non-provider local failure and the fallback chain aborts immediately instead of consuming candidate slots.Fixes #95474
Real behavior proof (required for external PRs)
Behavior addressed: Codex
missing_tool_result(synthetic error for hung native tool calls) triggers cross-provider model fallback, silently switching the user's model mid-conversation to a different provider that also cannot fix the local tool failure.Real setup tested:
Root cause: The outer fallback loop in
model-fallback.ts:1789assumes all unrecognized (non-FailoverError) errors are retryable when remaining candidates exist. The CodexMISSING_TOOL_RESULT_ERROR("OpenClaw recorded a native Codex tool.call without a matching tool.result before the turn completed.") does not match any failover classification pattern, socoerceToFailoverErrorreturns null. The raw error becomesnormalizedat line 1737,isKnownFailoveris false at line 1792, and the loop continues to the next model candidate — even though no other provider can fix a local command.Exact steps or command run after this patch:
cd /home/0668001085/workspace/openclaw-worktrees/fix/issue-95474 node_modules/.bin/vitest run src/agents/failover-error.test.ts --config vitest.config.ts --reporter=verbose node_modules/.bin/vitest run src/agents/model-fallback.test.ts --config vitest.config.ts --reporter=verbose pnpm format:check src/agents/failover-error.ts src/agents/failover-error.test.tsAfter-fix evidence:
Observed result after the fix:
isNonProviderRuntimeCoordinationErrornow returnstruefor errors containing the CodexMISSING_TOOL_RESULT_ERRORpattern (both direct and nested viacause/errorproperties). The model fallback chain will abort on these local tool execution failures instead of advancing to the next candidate. All existing tests continue to pass with no regressions.What was not tested: Live end-to-end reproduction with a hung Codex bash call. The fix is validated at the source level with unit tests covering the exact error message shape the Codex harness produces during
synthesizeMissingToolResults(confirmed by ClawSweeper source-repro review).Tests and validation
Risk checklist
Did user-visible behavior change?
Yes- Users encountering hung Codex native tool calls will no longer see their model silently switch to a different provider. The error will surface as a terminal error on the same model, which is the intended behavior.Did config, environment, or migration behavior change?
NoDid security, auth, secrets, network, or tool execution behavior change?
NoCurrent review state
What is the next action? Maintainer review requested