Repository navigation
[Bug]: A Muse turn stopped by the subscription quota shows as a provider error, not Limited #18236
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
A real run needs a used-up Meta subscription window. To reproduce on demand I put a small proxy between Muse and api.meta.ai (Muse's endpoint_transport setting) that answers POST /v1/responses with HTTP 429 and the body Meta sends for a used-up window:
{"error": {"code": "rate_limit_exceeded", "message": "Subscription quota exhausted. Your usage window resets soon.", "resets_at": 1791730859, "type": "rate_limit_error"}}- Enable the Muse Code provider on a host signed in to a Meta subscription.
- Send a Muse thread a message while the quota is used up (or the proxy refuses it).
Expected behavior
The thread is marked Limited, with Resume at reset and Snooze until reset, the way a Codex or Claude turn that hits its limit is. "Auto-resume limited threads" then works for Muse too.
Actual behavior
Muse treats the refusal as a quota stop (error_kind: tier_limit, not retried) and fails the turn with API error 429: Subscription quota exhausted. Your usage window resets soon. (rate_limit_error). T3 shows that as a red "Provider error" and marks the thread Failed, with no reset time and no way to resume at reset. The adapter maps every failed turn to provider_error or transport_error (adapter.ts). Muse also drops the resets_at Meta sends with the refusal.
Impact
Minor bug or occasional failure
Version or commit
main @ ed0f7b9
Environment
Linux (Ubuntu 24.04), web client in Chromium, Node 24.21.0, Muse Code 1.4.4 (1.4.4-R5419.1), muse-spark-1.3-contributor on a Meta subscription
Logs or stack traces
# muse exec --json against the same proxy (Muse 1.4.4), trimmed
task.lifecycle.status phase=stream_failed error_kind=tier_limit http_status=429 "failed meta model stream attempt 1/10"
run.terminal.failed reason="API error 429: Subscription quota exhausted. Your usage window resets soon. (rate_limit_error)"Screenshots, recordings, or supporting files
The refused turn and the thread's status on main:
Workaround
Wait for the window to reset and send the message again by hand.
Proposed fix
In packages/provider-muse's adapter, when a failed turn's message is Muse's quota refusal (API error 429 with "Subscription quota" or "usage limit"), report it as a usage_limit failure titled "Usage limit reached" instead of provider_error. Its resetAt comes from the newest usage/changed report Muse sent before the refusal: the latest reset among the windows that report showed used up. If no report showed a used-up window, the thread is still Limited, without a reset time. The change includes focused tests for the classification and the reset time, and before/after screenshots on web and mobile.
A working version of this was part of #17151, which was closed for missing screenshots. Once this is triaged I'll open a focused PR for it.
Filed with Claude Opus 5.5 in Claude Code.


Activity
juliusmarminge commentedon Oct 11, 2026
Note
Grok responding on behalf of Julius.
Bug confirmed on main: Muse's failed-turn path never emits
usage_limit. Inpackages/provider-muse/src/server/adapter.ts,finish()maps every failure toprovider_errorortransport_error(around themakeProviderFailurecall), thenturn/completedpasses throughresult.error?.messageunchanged. That is why a Meta quota stop (API error 429: Subscription quota exhausted… (rate_limit_error)) shows as a red Provider error and marks the thread Failed.Claude (
ClaudeAdapterV2), Codex (CodexAdapterV2), and Grok already classify the same kind of stop asusage_limit, which is what drives Limited, Resume at reset, Snooze, and auto-resume. Muse is missing that classification, not a new product surface.Related but separate from #18235 (Limits metering — enhancement / Ideas). Closed #17151 covered both; this issue is only the failure class. A focused PR that classifies the quota refusal as
usage_limit(and setsresetAtwhen a priorusage/changedreport has it) is welcome — include before/after of the Limited thread state per CONTRIBUTING.md.Screenshots for the pingdotgg#18236 fix (iOS, before and after)