Skip to content

fix(failover): classify upstream_error as server_error to trigger model fallback#96110

Closed
whiteyzy wants to merge 1 commit into
openclaw:mainfrom
whiteyzy:fix/95519-upstream-error-fallback
Closed

fix(failover): classify upstream_error as server_error to trigger model fallback#96110
whiteyzy wants to merge 1 commit into
openclaw:mainfrom
whiteyzy:fix/95519-upstream-error-fallback

Conversation

@whiteyzy

Copy link
Copy Markdown
Contributor

Summary

Fixes #95519: When a provider returns {"error":{"type":"upstream_error","message":"Upstream request failed"}}, model fallback does not trigger because classifyFailoverSignal does not recognize the upstream_error errorType. The turn ends with "LLM request failed." instead of trying configured fallback models.

Fix: In classifyFailoverSignal, classify errorType === "upstream_error" as server_error before falling through to message-based classification. This triggers model fallback for transient provider-side failures.

Real behavior proof

  • Behavior or issue addressed: upstream_error from providers (e.g. OpenAI responses API) does not trigger model fallback
  • Real environment tested: macOS, Node v22.22.3, latest upstream/main
  • Exact steps or command run after this patch:
node scripts/run-vitest.mjs run src/agents/embedded-agent-helpers/errors.test.ts --reporter=verbose
  • Evidence after fix (copied live output):
 ✓ classifyFailoverSignal upstream_error > classifies upstream_error errorType as server_error for model fallback (regression for #95519)
 ✓ classifyFailoverSignal upstream_error > does not classify unhandled error messages as server_error
 ...
 Test Files  1 passed (1)
      Tests  7 passed (7)
  • Observed result after fix: classifyFailoverSignal({errorType: "upstream_error", ...}) returns {kind: "reason", reason: "server_error"} — upstream_error is now recognized as a transient failure eligible for model fallback.
  • What was not tested: Live provider returning upstream_error with configured fallback models. The classification fix is deterministic — once classified as server_error, the existing fallback machinery handles the rest.

Tests and validation

Which commands did you run?

node scripts/run-vitest.mjs run src/agents/embedded-agent-helpers/errors.test.ts
# 7 passed (1 test file, 2 new tests added)

What regression coverage was added?

  • "classifies upstream_error errorType as server_error for model fallback (regression for #95519)" — verifies upstream_error → server_error
  • "does not classify unhandled error messages as server_error" — verifies no false positives

Risk checklist

Did user-visible behavior change? Yes — upstream_error now triggers model fallback instead of ending the turn immediately.
Did config, environment, or migration behavior change? No
Did security, auth, secrets, network, or tool execution behavior change? No
What is the highest-risk area? Could cause fallback loops if upstream_error is persistent across all models. Mitigation: existing fallback exhaustion logic already handles retry loops.

Closes #95519.


🤖 Generated with Claude Code
Co-Authored-By: Claude Code [email protected]

…model fallback

When a provider returns an error with type:upstream_error (e.g.
OpenAI responses API), classifyFailoverSignal returns null because
the errorType is not recognized, so model fallback never triggers
and the turn ends with 'LLM request failed.'

Add upstream_error → server_error classification in classifyFailoverSignal
so configured fallback models are attempted on transient provider-side
failures.

Closes openclaw#95519.
@clawsweeper

clawsweeper Bot commented Jun 23, 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: this PR is superseded by the merged canonical fix in #95542, and current main now covers both the helper-level upstream_error mapping and the embedded result fallback classifier path that this branch did not cover.

Root-cause cluster
Relationship: superseded
Canonical: #95542
Summary: This PR is superseded by the merged canonical PR that fixed the same upstream provider error fallback bug with broader runtime-path coverage.

Members:

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

Canonical path: #95542 merged and landed the fuller fix for #95519, including both assistant error classification and embedded result-classifier coverage.

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

Review details

Best possible solution:

Keep #95542 as the canonical landed fix and close this conflicting duplicate branch.

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

No current-main failure reproduction remains. The linked bug was source-reproducible before, but current main now maps upstream_error and covers the embedded provider payload classifier path.

Is this the best way to solve the issue?

No. The helper-only patch was a plausible partial fix when opened, but the merged current-main fix is better because it covers both the helper and embedded result-classifier boundaries.

Security review:

Security review cleared: The PR only changes internal TypeScript fallback classification and tests; it does not touch dependencies, workflows, secrets, package scripts, or supply-chain surfaces.

AGENTS.md: found and applied where relevant.

What I checked:

Likely related people:

  • mikasa0818: Authored the merged canonical fix branch that added upstream_error coverage across the helper and embedded result-classifier paths. (role: canonical fix author; confidence: high; commits: e67b78af640f, cfd8ba8fc81d; files: src/agents/embedded-agent-helpers/errors.ts, src/agents/embedded-agent-runner/result-fallback-classifier.ts, src/agents/embedded-agent-runner/result-fallback-classifier.test.ts)
  • altaywtf: Authored the follow-up refactor commit on the merged canonical PR and merged the landed fix. (role: canonical fix merger and refactor author; confidence: high; commits: f5a70ef7bb10, cfd8ba8fc81d; files: src/agents/embedded-agent-helpers/errors.ts, src/agents/embedded-agent-runner/result-fallback-classifier.ts)
  • steipete: Recent GitHub history shows model fallback and terminal-classifier work in the affected result fallback classifier and model failover docs. (role: recent fallback area contributor; confidence: medium; commits: 0314819f918a, 6719528316c0; files: src/agents/embedded-agent-runner/result-fallback-classifier.ts, docs/concepts/model-failover.md)
  • vincentkoc: Recent history shows shared model fallback and error normalization work adjacent to the provider/model fallback boundary. (role: adjacent fallback/runtime contributor; confidence: medium; commits: 80805ad7a583, aa3797c8d0d7; files: src/agents/model-fallback.ts, src/agents/embedded-agent-helpers/errors.ts)

Codex review notes: model internal, reasoning high; reviewed against 6cb82eaab865; fix evidence: commit cfd8ba8fc81d, main fix timestamp 2026-06-29T14:12:09+03:00.

@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: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels Jun 23, 2026
@clawsweeper

clawsweeper Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

@clawsweeper clawsweeper Bot closed this Jun 30, 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. 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]: Fallback should trigger on provider upstream_error / LLM request failed

1 participant