Skip to content

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

Description

@ElliotDrel

Summary

When a native Codex bash call hangs and is reaped as a synthetic missing_tool_result (the #86808 fail-closed path), OpenClaw's model-fallback engine classifies it as unclassified and fails over to the next configured provider (e.g. openai/gpt-5.4anthropic/claude-opus-4-8). A hung local shell command is not a model/provider fault, so failover cannot remedy it — it just silently switches the user's model mid-conversation. The 5-minute auto-override probe then reverts to primary, and the next long command repeats the cycle, producing visible provider "jumping."

Version

2026.5.28 (e932160). Model/routing: openai/gpt-5.4 (Codex OAuth), fallback anthropic/claude-opus-4-8.

Steps to reproduce

  1. Run a Codex-backed agent turn that issues a long-running / non-terminating shell command (e.g. a heavy parallel test suite).
  2. The native bash call never returns a result and is reaped at turn finalization as missing_tool_result.
  3. Observe session.ended status=error, then model fallback decision: decision=candidate_failed requested=openai/gpt-5.4 … next=anthropic/claude-opus-4-8.

Expected behavior

A local tool-execution failure (missing_tool_result; denied/timed-out/orphaned tool call) should be surfaced to the user and/or retried on the same model. It should be non-failover-eligible — no other provider can fix a local command, so it must not advance agents.defaults.model.fallbacks.

Actual behavior

missing_tool_result is classified unclassified, which the failover policy treats as "other unrecognized error with remaining candidates" → cross-provider model fallback fires. Each new turn re-requests the primary, the 5-minute probe clears the override, and the cycle repeats — the user sees the model bounce between providers with no credit/rate-limit cause.

Evidence

Two turns ~17 min apart, identical signature (model.completed fired; not a missing turn/completed as in #88312):

tool.call  bash id=…Fte1QSBG  ("bun run test" in a local repo)   @ T+0
…dozens of other bash calls complete normally…
tool.result bash id=…Fte1QSBG  status=failed reason=missing_tool_result   @ ~T+15min
model.completed
session.ended status=error
→ model fallback decision: candidate_failed requested=openai/gpt-5.4 next=anthropic/claude-opus-4-8

Codex app-server logged only codex_analytics::reducer: dropping turn tool count update: missing turn state … item_id=call_…Fte1QSBG for the hung call; no tool.result was ever produced.

Proposed fix

Add missing_tool_result / local-tool-execution failures to the non-failover classification set (alongside existing carve-outs) so they do not trigger model fallback. Optionally pair with a per-tool execution timeout so hung native shell commands fail fast with a real terminal result instead of stalling the whole turn.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:linked-pr-openClawSweeper 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:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.impact:session-stateSession, 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.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions