Skip to content

fix: user-pinned model falls back to global chain on quota exhaustion#88329

Open
Knowcheng wants to merge 4 commits into
openclaw:mainfrom
Knowcheng:fix/user-model-pin-fallback-on-quota-exhausted
Open

fix: user-pinned model falls back to global chain on quota exhaustion#88329
Knowcheng wants to merge 4 commits into
openclaw:mainfrom
Knowcheng:fix/user-model-pin-fallback-on-quota-exhausted

Conversation

@Knowcheng

@Knowcheng Knowcheng commented May 30, 2026

Copy link
Copy Markdown

Problem

When a user selects a model via `/model `, `modelOverride` is stored in `sessions.json` with `modelOverrideSource: "user"`. The `resolveEffectiveModelFallbacks` function returns `[]` for user-sourced overrides, making `hasFallbackCandidates = false`.

When the pinned model hits a long-term failure (weekly/monthly quota exhaustion, subscription limit), every subsequent message fails with:

```
⚠️ All models are temporarily rate-limited. Please try again in a few minutes.
```

This is a complete outage — no recovery path short of manually editing `sessions.json`.

Root cause (`src/agents/agent-scope.ts`):

```typescript
if (!canUseConfiguredFallbacks) {
return []; // disables entire fallback chain for user-pinned sessions
}
```

Reproduction:

  1. Use `/model glm-5` (or any model with a weekly quota)
  2. Exhaust the weekly quota (error 1310 from zhipuai)
  3. Every new message fails — even after gateway restart — because `sessions.json` persists `modelOverride` across sessions and new sessions inherit the pin

Fix

Return the global fallback chain instead of `[]`. The user's intent when pinning a model is to prefer it, not to disable recovery when it's unavailable. The pinned model remains the first candidate and is always tried first.

For subagent sessions, the subagent-specific fallback chain is used (same as auto-selected subagents), rather than the generic agent/default chain.

Behavior change

Scenario Before After
User-pinned model temporarily rate-limited Error surfaced Falls back to next model
User-pinned model quota exhausted (days/weeks) Permanent outage Falls back to next model
User-pinned subagent model quota exhausted Permanent outage Falls back to subagent fallback chain
No model pin / auto-fallback pin Unchanged Unchanged

Real behavior proof

Two occurrences captured in local gateway logs on 2026-05-30 (before this fix), both showing the same subagent `zai/glm-5` session hitting the weekly quota with zero fallback candidates:

Occurrence 1 — 2026-05-30T13:14 CST

Session `b640381c` (subagent `a093b44d`), run `f6f7e336`:

```

trajectory event: model.fallback_step

{
"type": "model.fallback_step",
"ts": "2026-05-30T05:14:09.631Z",
"sessionKey": "agent:main:subagent:a093b44d-8405-4e1d-a3bd-00ccb1c2b7e5",
"provider": "zai",
"modelId": "glm-5",
"data": {
"fallbackStepFromModel": "zai/glm-5",
"fallbackStepFromFailureReason": "rate_limit",
"fallbackStepFromFailureDetail": "429 您已达到每周/每月使用上限,您的限额将在 2026-05-31 10:00:31 重置。",
"fallbackStepChainPosition": 1,
"fallbackStepFinalOutcome": "chain_exhausted" // ← chain position 1 + exhausted = 0 candidates
}
}
```

Gateway log at the same moment:
```
2026-05-30T13:14:09.778+08:00 [ws] ⇄ res ✗ agent errorCode=UNAVAILABLE
errorMessage=FailoverError: ⚠️ API rate limit reached. Please try again later.
runId=f6f7e336-85e2-4db7-825e-59ec76b32a07
```

Occurrence 2 — 2026-05-30T15:23 CST (2 hours later, same quota, still no fallback)

Session `f455173a` (subagent `90f819dc`), run `625ffb86`:

```

trajectory event: model.fallback_step

{
"type": "model.fallback_step",
"ts": "2026-05-30T07:23:05.922Z",
"sessionKey": "agent:main:subagent:90f819dc-fdfa-4ad3-9b3f-8c16b3cb250a",
"provider": "zai",
"modelId": "glm-5",
"data": {
"fallbackStepFromModel": "zai/glm-5",
"fallbackStepFromFailureReason": "rate_limit",
"fallbackStepFromFailureDetail": "429 您已达到每周/每月使用上限,您的限额将在 2026-05-31 10:00:31 重置。",
"fallbackStepChainPosition": 1,
"fallbackStepFinalOutcome": "chain_exhausted"
}
}
```

Gateway log:
```
2026-05-30T15:23:06.062+08:00 [ws] ⇄ res ✗ agent errorCode=UNAVAILABLE
errorMessage=FailoverError: ⚠️ API rate limit reached. Please try again later.
runId=625ffb86-eee4-4e97-8b7b-7bcdad2bb55c
```

Key signal: `fallbackStepChainPosition: 1` with `fallbackStepFinalOutcome: "chain_exhausted"` means the fallback chain had zero candidates — the bug. After the fix, the same quota-exhaustion event would advance to the next model in the configured chain instead of immediately declaring `chain_exhausted`.

When a user explicitly selects a model via `/model <name>`, the session
stores `modelOverride` with `modelOverrideSource: "user"`. Previously,
`resolveEffectiveModelFallbacks` returned `[]` for user-sourced overrides,
disabling the entire fallback chain for that session.

This causes a complete outage when the pinned model hits a long-term limit:
- Weekly/monthly quota exhaustion (error 1310 from zhipuai/GLM)
- Subscription limits (openai-codex)

In these cases, `hasFallbackCandidates` becomes `false`, the runner sets
`fallbackConfigured: false`, and every message surfaces:
  "⚠️ All models are temporarily rate-limited. Please try again in a few minutes."

The user's intent when pinning a model is to *prefer* it, not to permanently
disable recovery when it becomes unavailable. The pinned model is always the
first candidate and continues to be tried first — this change only affects
what happens when it fails.

Fix: when `canUseConfiguredFallbacks` is false (user-sourced pin), return the
global fallback chain (`agentFallbacksOverride ?? defaultFallbacks`) instead of
`[]`. This is consistent with how `modelOverrideSource === "auto"` already
behaves — it falls through to the same return at lines 551-552.
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 30, 2026
@clawsweeper

clawsweeper Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 5, 2026, 5:07 PM ET / 21:07 UTC.

Summary
The PR adds a quota-exhaustion-only fallback path for user and legacy model pins across agent-command and auto-reply runs, expands usage-limit matchers, and updates tests/docs to describe user pins as recoverable preferences.

PR surface: Source +80, Tests +128, Docs 0. Total +208 across 10 files.

Reproducibility: yes. at source level: current main returns an empty fallback list for user-sourced model overrides, and the PR discussion includes before-fix logs showing one-candidate exhaustion. I did not run a live quota-exhausted provider setup.

Review metrics: 1 noteworthy metric.

  • User-pin fallback contract: 1 persisted session behavior changed. User and legacy model overrides can become quota-triggered fallback preferences instead of exact selections, which matters for upgrades and provider/auth routing.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🧂 unranked krab
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Add redacted after-fix logs, terminal output, live output, or a recording showing quota fallback progression.
  • Rebase or otherwise resolve the dirty merge state against current main.
  • Move quota expansion before cooldown skip/suspend handling and cover current OpenClaw/upstream Codex usage-limit strings.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body and comments show before-fix or complementary logs only; the contributor still needs redacted after-fix terminal/log/live output or a recording showing a pinned quota-exhausted model advancing to a configured fallback. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P2] Persisted user and legacy model pins would start routing to configured fallback providers on quota exhaustion after upgrade, which changes documented session-selection semantics.
  • [P2] Quota fallback expansion still happens after cooldown skip/suspend handling, so already-cooldowned pinned providers can still exhaust as a single-candidate run.
  • [P1] The Codex quota matcher misses current OpenClaw and upstream Codex usage-limit messages, leaving part of the promised recovery path uncovered.
  • [P1] The live PR is dirty/conflicting, so maintainers have not reviewed the exact current-main merge result.
  • [P1] Contributor after-fix real behavior proof is still missing.

Maintainer options:

  1. Rebase, repair, and prove quota fallback (recommended)
    Resolve the dirty merge state, move quota expansion ahead of cooldown/suspend decisions, cover current usage-limit strings, and add redacted after-fix runtime proof before merge.
  2. Accept the semantics change explicitly
    Maintainers can choose quota-only fallback for pinned sessions, but should own the compatibility and provider-routing behavior in the PR before landing.
  3. Pause for strict-pin policy
    If exact user selections should remain strict, pause or close this branch and route recovery through a separate explicit policy or recovery surface.

Next step before merge

  • [P1] Maintainer review is needed for the pinned-model semantics change, the dirty merge state, the unresolved P1 blockers, and missing contributor after-fix proof.

Maintainer decision needed

  • Question: Should user-sourced and legacy model pins be allowed to fall back to the configured chain on periodic quota or subscription exhaustion while remaining strict for transient failures?
  • Rationale: That choice changes persisted session semantics and can route a pinned session through different provider/auth profiles after upgrade, so correctness fixes alone do not settle product intent.
  • Likely owner: steipete — steipete has recent history across the model fallback semantics and docs surfaces affected by this product choice.
  • Options:
    • Accept quota-only fallback after repair (recommended): Allow pinned models to recover from long-term quota/subscription exhaustion once the cooldown and matcher blockers are fixed and after-fix proof is supplied.
    • Keep exact pins strict: Preserve the documented exact-selection contract and solve recovery through explicit user action, doctor/setup guidance, or a separate opt-in policy.
    • Broaden user-pin fallback: Treat user pins as preferences for more provider failures, but require a broader compatibility design and tests before merging.

Security
Cleared: No workflow, dependency, lockfile, credential-storage, or supply-chain changes were found; provider/auth routing impact is tracked as merge risk.

Review findings

  • [P1] Expand quota fallbacks before cooldown skips — src/agents/model-fallback.ts:1513-1514
  • [P1] Match actual Codex usage-limit text — src/agents/embedded-agent-helpers/failover-matches.ts:10
Review details

Best possible solution:

Land a rebased quota-only fallback fix only after maintainers accept the pinned-model semantics change, quota candidates are available before cooldown/suspend decisions, current OpenClaw and upstream Codex usage-limit strings are covered, and redacted after-fix proof shows fallback progression.

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

Yes at source level: current main returns an empty fallback list for user-sourced model overrides, and the PR discussion includes before-fix logs showing one-candidate exhaustion. I did not run a live quota-exhausted provider setup.

Is this the best way to solve the issue?

No, not yet. The quota-only direction is plausible, but the expansion point is too late for cooldown-precheck exhaustion, the Codex matcher is too narrow, and the persisted-pin semantics change needs maintainer acceptance.

Full review comments:

  • [P1] Expand quota fallbacks before cooldown skips — src/agents/model-fallback.ts:1513-1514
    This still runs only after runFallbackAttempt returns. If the pinned provider already has all auth profiles in persisted cooldown, the loop can take the cooldown suspend/skip path before this branch runs, so the reported All models failed (1) shape can persist for already-cooldowned quota providers.
    Confidence: 0.9
  • [P1] Match actual Codex usage-limit text — src/agents/embedded-agent-helpers/failover-matches.ts:10
    The new regex only matches you have hit your ... usage limit, but current OpenClaw emits You've reached your Codex subscription usage limit. and upstream Codex emits You've hit your usage limit... / The usage limit has been reached. Pinned Codex quota errors can therefore keep the empty fallback chain.
    Confidence: 0.92

Overall correctness: patch is incorrect
Overall confidence: 0.9

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 51771c3a1485.

Label changes

Label justifications:

  • P1: The PR targets a real user-facing agent outage on long-term quota exhaustion, but the current patch still has merge-blocking correctness and proof gaps.
  • merge-risk: 🚨 compatibility: Persisted user and legacy model pins may begin falling through to configured fallback models after upgrade.
  • merge-risk: 🚨 auth-provider: Quota-triggered fallback can move a pinned session onto a different provider and auth-profile chain.
  • merge-risk: 🚨 availability: The current patch can still leave already-cooldowned pinned providers exhausting a run before fallback expansion.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body and comments show before-fix or complementary logs only; the contributor still needs redacted after-fix terminal/log/live output or a recording showing a pinned quota-exhausted model advancing to a configured fallback. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +80, Tests +128, Docs 0. Total +208 across 10 files.

View PR surface stats
Area Files Added Removed Net
Source 5 83 3 +80
Tests 3 129 1 +128
Docs 2 5 5 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 10 217 9 +208

What I checked:

  • Repository policy read: Root AGENTS.md and scoped src/agents and docs AGENTS.md were read; the review applied the policy that provider routing, auth/session state, persisted preferences, and fallback behavior are compatibility-sensitive. (AGENTS.md:17, 51771c3a1485)
  • Current main does not already implement the central behavior: Current main returns [] when a session model override cannot use configured fallbacks, preserving strict user/legacy pin behavior. (src/agents/agent-scope.ts:567, 51771c3a1485)
  • PR adds a separate quota fallback chain: The PR keeps resolveEffectiveModelFallbacks strict and adds resolveQuotaExhaustionFallbacks for periodic quota recovery. (src/agents/agent-scope.ts:561, 8b388584f5c9)
  • Cooldown blocker remains: The PR expands quota fallback candidates only after runFallbackAttempt returns an error; its own head can take the cooldown suspend path earlier for a single pinned candidate. (src/agents/model-fallback.ts:1513, 8b388584f5c9)
  • Current main cooldown path is now more complex: Current main can suspend lanes from auth-profile cooldown handling before the provider call, so a rebased fix needs to integrate quota expansion before this decision surface. (src/agents/model-fallback.ts:1471, 51771c3a1485)
  • Codex matcher remains too narrow: The PR matcher accepts only the non-contracted 'you have hit your ... usage limit' wording and misses current OpenClaw and upstream Codex variants. (src/agents/embedded-agent-helpers/failover-matches.ts:10, 8b388584f5c9)

Likely related people:

  • steipete: Recent commits and docs work touched agent fallback semantics, model selection documentation, and broad agent runtime ownership around this path. (role: recent area contributor; confidence: medium; commits: 634174f050b4, 0314819f918a, bb46b79d3c14; files: src/agents/model-fallback.ts, src/agents/agent-scope.ts, docs/concepts/model-failover.md)
  • joelnishanth: Recent work changed session suspension deferral in the same model fallback path where quota fallback needs to interact with cooldown/suspend behavior. (role: recent fallback suspension contributor; confidence: medium; commits: 9fd9aa5fcdd2; files: src/agents/model-fallback.ts)
  • 849261680: Recent commits touched primary cooldown probing and bound-route fallback/session behavior adjacent to the remaining blocker. (role: recent cooldown behavior contributor; confidence: medium; commits: 6da3b1f6a351, a0ed4273ee68; files: src/agents/model-fallback.ts, src/agents/agent-scope.ts)
  • amknight: Recent work owns the Codex usage-limit recovery copy that the PR matcher must recognize. (role: recent Codex usage-copy contributor; confidence: medium; commits: c3c8a65373d5; files: extensions/codex/src/app-server/rate-limits.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (1 earlier review cycle)
  • reviewed 2026-06-28T12:25:52.028Z sha 8b38858 :: needs real behavior proof before merge. :: [P1] Expand quota fallbacks before cooldown skips | [P1] Match current Codex usage-limit messages

@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. P1 High-priority user-facing bug, regression, or broken workflow. 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 May 30, 2026
@byungskers

Copy link
Copy Markdown

I think this needs a bit more design/coverage before landing. This change flips modelOverrideSource === "user" from a strict pin into a preference, but it does so in the shared fallback helper without updating the documented/tested contract or the subagent-specific branch just below. In particular, a user-pinned subagent session looks like it would now skip the subagent fallback path and inherit the generic default chain instead. If the intended product change is "user pins may fall back", I'd strongly suggest landing it together with updated docs/tests and an explicit decision about whether subagents should keep their dedicated fallback chain.

… preference semantics

- In the !canUseConfiguredFallbacks branch, check isSubagentSessionKey first so
  user-pinned subagent sessions use the subagent fallback chain (same as auto-selected
  subagents) rather than the generic agent/default chain.
- Update agent-scope tests: user-pinned and legacy-source sessions now return the
  configured fallback list instead of [].
- Update models.md and model-failover.md to describe user pins as a preference
  (pinned model tried first, falls back on long-term quota exhaustion) rather than
  a strict lock.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@openclaw-barnacle openclaw-barnacle Bot added the docs Improvements or additions to documentation label May 31, 2026
@Knowcheng

Copy link
Copy Markdown
Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

…on B)

Revert the earlier broad fix that allowed user-pinned sessions to use
the configured fallback chain for any failure type.  Instead, keep
resolveEffectiveModelFallbacks returning [] for user-pinned sessions
(strict pin for transient errors), and introduce a targeted recovery
path in runWithModelFallback that activates only on permanent periodic
quota signals (weekly/monthly limits detected via
isPeriodicUsageLimitErrorMessage).

Changes:
- resolveEffectiveModelFallbacks: reverts !canUseConfiguredFallbacks
  branch back to return []
- resolveQuotaExhaustionFallbacks: new exported function providing the
  fallback chain for quota-exhaustion recovery (subagent-aware,
  mirrors the configured chain logic)
- runWithModelFallback: adds quotaExhaustionFallbacksOverride param;
  on primary failure, if isPrimary && !hasFallbackCandidates and the
  error matches the periodic quota pattern, candidates is expanded
  in-place so the loop continues with the configured fallback chain
- agent-command.ts: pre-computes quotaExhaustionFallbacksOverride when
  effectiveFallbacksOverride is [] (user-pinned sessions only) and
  passes it to runWithModelFallback
- agent-scope.test.ts: reverts 4 assertions back to toStrictEqual([]),
  adds new test block for resolveQuotaExhaustionFallbacks

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@Knowcheng

Copy link
Copy Markdown
Author

@clawsweeper review

@clawsweeper

clawsweeper Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

…nner

Addresses two P1/P2 findings from the Option B review:

1. Extend isPeriodicUsageLimitErrorMessage to cover missing signals:
   - Z.ai Chinese weekly/monthly quota message: 每[周月].*使用上限
     (real error from logs: 您已达到每周/每月使用上限)
   - Codex usage limit: You have hit your (ChatGPT )?usage limit
     (produced by openai-codex-responses.ts for error 1310/usage_limit_reached)
   Adds matcher tests covering all three patterns.

2. Wire quotaExhaustionFallbacksOverride through resolveModelFallbackOptions
   so channel/auto-reply runners (agent-runner-execution.ts, followup-runner.ts)
   also expand the candidate chain on permanent quota for user-pinned sessions.
   The agent-runner-run-params.ts function already owns fallbacksOverride
   resolution; quotaExhaustionFallbacksOverride follows the same pattern.
   Adds test cases covering user-pin expansion and non-expansion for auto.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@Knowcheng

Copy link
Copy Markdown
Author

@clawsweeper review

@clawsweeper

clawsweeper Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@kumaxs

kumaxs commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Live repro: 7 consecutive All models failed (1) matching your chain_exhausted pattern

Strong complementary evidence for the "chain exhausted after 1 attempt" pattern this PR fixes. Real gateway log from a plugin-internal narrative generation cron — same root cause as your zai/glm-5 repro, but observed in a different code path (memory-core narrative generation instead of subagent user-pinned).

Environment

  • OpenClaw v2026.6.6 (8c802aa) on macOS arm64
  • model.primary minimax/MiniMax-M3, fallbacks [minimax/MiniMax-M2.7, opencode-go/deepseek-v4-flash]
  • gateway on https://exo-service-1.tail44cc76.ts.net (Tailscale serve)
  • MiniMax 5-hour Token Plan: 2056/2062 used at 04:30

Trajectory (7 consecutive failures within 19 seconds)

2026-06-14T04:30:33.783+08:00 [plugins] memory-core: narrative generation used fallback for deep phase because the narrative run ended with status=error (FallbackSummaryError: All models failed (1): minimax/MiniMax-M2.7: Provider minimax is in cooldown (suspending lanes) (rate_limit)).
2026-06-14T04:30:48.630+08:00 [plugins] memory-core: narrative generation used fallback for light phase because the narrative run ended with status=error (FallbackSummaryError: All models failed (1): minimax/MiniMax-M2.7: Provider minimax is in cooldown (suspending lanes) (rate_limit)).
2026-06-14T04:30:48.801+08:00 [plugins] memory-core: narrative generation used fallback for rem phase because the narrative run ended with status=error (FallbackSummaryError: All models failed (1): minimax/MiniMax-M2.7: Provider minimax is in cooldown (suspending lanes) (rate_limit)).
2026-06-14T04:30:48.885+08:00 [plugins] memory-core: narrative generation used fallback for light phase because the narrative run ended with status=error (FallbackSummaryError: All models failed (1): minimax/MiniMax-M2.7: Provider minimax is in cooldown (suspending lanes) (rate_limit)).
2026-06-14T04:30:52.964+08:00 [plugins] memory-core: narrative generation used fallback for rem phase because the narrative run ended with status=error (FallbackSummaryError: All models failed (1): minimax/MiniMax-M2.7: Provider minimax is in cooldown (suspending lanes) (rate_limit)).
2026-06-14T04:30:53.120+08:00 [plugins] memory-core: narrative generation used fallback for light phase because the narrative run ended with status=error (FallbackSummaryError: All models failed (1): minimax/MiniMax-M2.7: Provider minimax is in cooldown (suspending lanes) (rate_limit)).
2026-06-14T04:30:53.201+08:00 [plugins] memory-core: narrative generation used fallback for rem phase because the narrative run ended with status=error (FallbackSummaryError: All models failed (1): minimax/MiniMax-M2.7: Provider minimax is in cooldown (suspending lanes) (rate_limit)).
2026-06-14T05:00:28.025+08:00 [session-suspension] auto-resumed lane after suspension TTL

Pattern match to your fallbackStepChainPosition: 1 + chain_exhausted

Same signature: All models failed (1) = 1 attempt before declaring exhausted. The narrative cron was running on M2.7 (auto-fallback from M3), M2.7 itself was in cooldown, and the resolved fallback chain was empty — so the system declared chain exhausted after the first (and only) candidate.

This is the same root cause as your zai/glm-5 subagent case, but for the plugin-internal narrative path: the resolved fallback list is [] for runs that should be using agents.defaults.model.fallbacks.

What the fix would look like for this path

The minimal change described in this PR — resolveEffectiveModelFallbacks returning the global chain instead of [] for the user-pinned case — is the correct shape. Plugin-internal runs (memory-core narrative, dreaming) likely hit the same code path for the same reason: the auto-fallback override on a quota-exhausted lane should still be allowed to walk the configured chain instead of declaring exhausted after 1 attempt.

Test scope suggestion

If you have bandwidth to add a regression test for the plugin-internal / cron path alongside the subagent user-pinned test, that would close the surface. The narrative log signature ([plugins] memory-core: narrative generation used fallback for ...) is a reliable marker for that code path.

Related (read for full context)

  • PR #80829 — followup-runner silent drop fix (complementary; different code path)
  • PR #92676userMessage field data plumbing (the visible-notification half; explicitly defers delivery hook to a follow-up)
  • Issue #92672 — RFC umbrella for the main-path visible-notification gap

@clawsweeper

clawsweeper Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

@Knowcheng thanks for the PR. ClawSweeper is still waiting on real behavior proof before this can move forward.

Useful proof can be a screenshot, short video, terminal output, copied live output, linked artifact, or redacted logs that show the changed behavior after the fix. Please redact private tokens, phone numbers, private endpoints, customer data, and anything else sensitive.

Once proof is added to the PR body or a comment, ClawSweeper or a maintainer can re-check it.

@clawsweeper clawsweeper Bot added the merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. label Jun 29, 2026
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jun 29, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jul 20, 2026
@clawsweeper

clawsweeper Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@Knowcheng thanks for the PR. ClawSweeper is still waiting on real behavior proof before this can move forward.

Useful proof can be a screenshot, short video, terminal output, copied live output, linked artifact, or redacted logs that show the changed behavior after the fix. Please redact private tokens, phone numbers, private endpoints, customer data, and anything else sensitive.

Once proof is added to the PR body or a comment, ClawSweeper or a maintainer can re-check it.

@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jul 23, 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 docs Improvements or additions to documentation merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P1 High-priority user-facing bug, regression, or broken workflow. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants