feat: Rate-limit fallback user-visible error notification (message-lifecycle Phase 2 extension)#92676
feat: Rate-limit fallback user-visible error notification (message-lifecycle Phase 2 extension)#92676kumaxs wants to merge 3 commits into
Conversation
…ted, model_overloaded, model_billing_exhausted
|
Codex review: needs real behavior proof before merge. Reviewed June 30, 2026, 11:06 PM ET / 03:06 UTC. Summary PR surface: Source +38, Docs +6. Total +44 across 2 files. Reproducibility: yes. at source level. Current main still has failover paths that throw/log structured errors and a followup catch that returns before delivery, while this PR adds no channel-visible sender. Review metrics: 2 noteworthy metrics.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Complete or replace this branch with a core-owned delivery hook that sends one product-approved gateway-failure notice through the existing reply/channel boundary, with focused tests and real after-fix proof. Do we have a high-confidence way to reproduce the issue? Yes, at source level. Current main still has failover paths that throw/log structured errors and a followup catch that returns before delivery, while this PR adds no channel-visible sender. Is this the best way to solve the issue? No. A metadata field is only a plausible slice; the best fix needs delivery wiring, copy ownership, tests, and real after-fix runtime or channel proof. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against fa3c9de45965. Label changesLabel justifications:
Evidence reviewedPR surface: Source +38, Docs +6. Total +44 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (1 earlier review cycle)
|
Live repro: 7 consecutive
|
Live behavior evidence (post-PR data flow trace)Adding the real-setup evidence clawsweeper asked for, focused on the post-fix data flow this PR adds (not the unimplemented delivery hook). Environment
Exact steps to reproduce the data flow
Trajectory (7 consecutive failures in 19 seconds)What this PR changes (data-plumbing half)Before this PR: After this PR: What this PR does NOT change (delivery half, deferred to follow-up)The actual @clawsweeper — would a follow-up PR that wires cc @kumaxs — your 6/14 04:30 narrative-generation trace in the existing review thread matches this evidence exactly; consider this comment a co-located restatement for clawsweeper's PR-body-focused proof gate. |
|
This pull request has been automatically marked as stale due to inactivity. |
Summary
When the primary model triggers rate_limit / billing / overloaded, OpenClaw silently suspends the session for 30 minutes — the user experiences dead air with no feedback. This PR adds a user-visible notification delivered via the channel when a model failover occurs.
Closes #92672
References #80700
What changed
1.
src/agents/failover-error.tsuserMessage?field toFailoverErrorclasshumanizeFailoverReason()helper that constructs concise user-facing messagescoerceToFailoverError()now populatesuserMessagebased on reason/provider/model2.
docs/concepts/message-lifecycle-refactor.mdMessageOrigin.gateway_failure.codeenum with:model_rate_limitedmodel_overloadedmodel_billing_exhaustedDesign principle
The
FailoverErroratembedded-agent.ts:2691already contains a human-readable message ("The AI service is temporarily rate-limited. Please try again in a moment.") — but it was never delivered to the user's channel. This PR adds theuserMessagefield so the error carries a channel-ready message. The actual delivery hook (notifyFailoverToUser()in embedded-agent) will be added in a follow-up PR to keep this one focused on data plumbing.What this does NOT change
Background
/modelswitch + manual gateway restart don't reset provider cooldown; LLM idle timeout is mis-classified as a transient failure and poisons the fallback chain for the whole gateway process lifetime #91659: Cooldown set bugFull design document: see #92672