Skip to content

fix(agents): classify missing_tool_result as tool_error to prevent cross-provider failover#95488

Closed
wings1029 wants to merge 2 commits into
openclaw:mainfrom
wings1029:fix/issue-95474-missing-tool-result-fallback
Closed

fix(agents): classify missing_tool_result as tool_error to prevent cross-provider failover#95488
wings1029 wants to merge 2 commits into
openclaw:mainfrom
wings1029:fix/issue-95474-missing-tool-result-fallback

Conversation

@wings1029

@wings1029 wings1029 commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

When a local tool execution fails (e.g. hung bashmissing_tool_result), the error was classified as unclassified which triggers cross-provider model fallback. A hung local command is not a model/provider fault, so switching providers cannot remedy it — the user sees the model bounce between providers with no benefit.

Add tool_error as a new FailoverReason and detect missing_tool_result in error classification to prevent cross-provider failover.

Fixes #95474.

Change

File Change
embedded-agent-helpers/types.ts Add "tool_error" to FailoverReason union
embedded-agent-helpers/errors.ts Detect missing_tool_result in classifyFailoverClassificationFromMessage and classifyProviderRuntimeFailureKind
failover-policy.ts Add tool_error to shouldPreserveTransientCooldownProbeSlot (non-failover)
auth-profiles/types.ts Add "tool_error" to AuthProfileFailureReason
runtime-plan/types.ts Add "tool_error" to AgentRuntimeFailoverReason

Evidence

Suite Result
embedded-agent-helpers.isbillingerrormessage.test.ts ✅ 143/143 passed
runtime-plan/types.compat.test.ts ✅ 3/3 passed
oxlint + boundary dts ✅ clean

Risk

  • Low risk: adds a new error classification without changing existing behavior
  • tool_error is treated as non-transient — no cooldown probe, no cross-provider failover
  • The existing shouldPreserveTransientCooldownProbeSlot guard ensures fallback loop does not advance to next candidate for tool_error

🤖 Generated with Claude Code

@wings1029
wings1029 requested a review from a team as a code owner June 21, 2026 04:45
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: XS triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jun 21, 2026
@clawsweeper

clawsweeper Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

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 linked missing-tool-result fallback bug as the open, proof-positive sibling PR, but its tool_error reason path is broader and still flows through existing fallback/auth-profile decision code.

Root-cause cluster
Relationship: superseded
Canonical: #95543
Summary: This PR and the sibling both target the same linked missing_tool_result fallback bug; the sibling is open, mergeable, proof-positive, and uses the narrower existing failover-boundary seam.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Canonical path: Let #95543 remain the canonical implementation path if maintainers agree, because it uses the existing non-provider abort boundary and includes runtime-boundary proof.

So I’m closing this here and keeping the remaining discussion on #95543.

Review details

Best possible solution:

Let #95543 remain the canonical implementation path if maintainers agree, because it uses the existing non-provider abort boundary and includes runtime-boundary proof.

Do we have a high-confidence way to reproduce the issue?

Yes at source level: current main synthesizes missing_tool_result, and the failover loop/decision policy can still advance candidate models for recognized non-timeout failover failures. I did not run the slow live hanging-shell scenario.

Is this the best way to solve the issue?

No: this branch classifies the sentinel as a new failover reason, but current decision code still treats concrete non-timeout failover reasons as profile-rotation/model-fallback candidates. The better fix is a narrow local non-provider abort guard with provider-metadata precedence tests.

Security review:

Security review cleared: The diff changes TypeScript error classification/type unions only; no dependency, CI, secret, permission, install, or supply-chain surface changed.

AGENTS.md: found and applied where relevant.

What I checked:

  • Live PR state: Live GitHub reports this PR open, mergeable, externally authored, and still labeled as needing proof after the force-pushed head 0db873a. (0db873a5050c)
  • OpenClaw sentinel source: Current main records missing native Codex tool completions as failed tool.result events with reason: "missing_tool_result" and promotes the stable missing-tool-result text into the local error path. (extensions/codex/src/app-server/event-projector.ts:1627, 4fc504d321b6)
  • Current main fallback behavior: runWithModelFallback only aborts local coordination/context/harness errors before normalization; otherwise recognized failover errors and unrecognized errors with remaining candidates can continue to later fallback candidates. (src/agents/model-fallback.ts:1721, 4fc504d321b6)
  • Current main decision policy: A concrete non-timeout failover reason goes to profile rotation and then fallback_model when fallbacks are configured, so a new tool_error reason is not enough to stop model fallback. (src/agents/embedded-agent-runner/run/failover-policy.ts:202, 4fc504d321b6)
  • Auth-profile propagation: resolveAuthProfileFailureReason returns most non-null failover reasons, and auth-profile usage stores non-rate_limit/non-timeout reasons as profile-wide cooldown reasons; adding a local tool reason to auth failure types is therefore compatibility-sensitive. (src/agents/embedded-agent-runner/run/auth-profile-failure-policy.ts:14, 4fc504d321b6)
  • Codex dependency contract: Upstream Codex models local exec command lifecycle as begin/end events with ExecCommandStatus values including Failed; the missing_tool_result sentinel is an OpenClaw projection/failover concern, not an upstream provider-auth reason. (../codex/codex-rs/protocol/src/protocol.rs:3422, 92d2e1df7079)

Likely related people:

  • zhangguiping-xydt: GitHub commit metadata and local blame tie commit bead84f to the current fallback decision policy, model-fallback abort block, and current missing-result projection lines. (role: recent area contributor; confidence: high; commits: bead84f0ee6e; files: src/agents/embedded-agent-runner/run/failover-policy.ts, src/agents/model-fallback.ts, extensions/codex/src/app-server/event-projector.ts)
  • steipete: Merged PR Fix live model inference edge cases #88946 added the missing_tool_result synthesis path and tests that this failover bug builds on. (role: adjacent feature owner; confidence: high; commits: 9ead0ae9219e; files: extensions/codex/src/app-server/event-projector.ts, extensions/codex/src/app-server/event-projector.test.ts)
  • brokemac79: PR fix(failover): fallback on replay-safe prompt timeouts #96142 recently changed the same failover decision function for prompt-timeout fallback behavior. (role: adjacent contributor; confidence: medium; commits: 0da26499dac2; files: src/agents/embedded-agent-runner/run/failover-policy.ts, src/agents/embedded-agent-runner/run/failover-policy.test.ts)
  • obviyus: GitHub commit metadata lists this handle as committer for bead84f, which currently owns the central fallback/projection lines in this checkout. (role: recent committer; confidence: medium; commits: bead84f0ee6e; files: src/agents/embedded-agent-runner/run/failover-policy.ts, src/agents/model-fallback.ts, extensions/codex/src/app-server/event-projector.ts)

Codex review notes: model internal, reasoning high; reviewed against 4fc504d321b6.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels Jun 21, 2026
wings1029 and others added 2 commits June 26, 2026 12:20
…oss-provider failover

When a local tool execution fails (e.g. hung bash → missing_tool_result),
the error was classified as 'unclassified' which triggers cross-provider
model fallback. A hung local command is not a model/provider fault, so
switching providers cannot remedy it.

Add 'tool_error' FailoverReason and classify any error message containing
'missing_tool_result' as tool_error. This prevents the failover engine
from silently switching the user's model mid-conversation.

Fixes openclaw#95474

Co-Authored-By: Claude <[email protected]>
@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jun 26, 2026
@wings1029
wings1029 force-pushed the fix/issue-95474-missing-tool-result-fallback branch from 4c67386 to 0db873a Compare June 26, 2026 05:46
@clawsweeper

clawsweeper Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

@clawsweeper clawsweeper Bot closed this Jun 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XS status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: missing_tool_result (local tool-execution failure) is classified unclassified and triggers cross-provider model fallback

1 participant