Repository navigation
Description
Note
Claude Opus 5.5 responding on behalf of Ângelo.
What happened
A long Muse thread kept failing with "Usage limit reached. Retry after 20:24." The user retried and got the same error. Meanwhile muse usage showed the 5-hour window at 20% and the weekly allowance at 45%, so the label and the suggested remedy did not match the account's actual state.
Diagnosis
T3's Muse adapter treats every failure that carries error.quota as usage_limit, titles it "Usage limit reached", and offers "Resume at reset" at quota.resetsAtMs. That holds even when the latest usage/changed report from the same host shows no window at 100%.
MuseTurnCompleted.errorinpackages/provider-muse/src/server/protocol.tsdecodes onlymessageandquota.resetsAtMs. Muse also sendsquota.limitKind, here"tierLimit", andretryable, herefalse. Both are dropped before classification.- In
packages/provider-muse/src/server/adapter.ts,usageLimitedis true wheneverquota !== undefined.museUsageLimitResetAtinusageLimits.tsreadslatestSubscriptionUsagebut only adds windows at 100% or more, so it falls back toquota.resetsAtMsand never surfaces the contradiction. - The test "limits a stop Muse types as quota at the reset it reports" in
adapter.test.tspinslimitKind: "tierLimit"tousage_limitand checks only the reset time.
Muse's MSP schema, exported with muse schema generate-json-schema, says TurnError.quota is present iff the stopping failure was the quota class, and that clients branch on its presence. LimitKind is an open enum whose only current value is tierLimit. So keeping the usage_limit class, which makes the run resumable per #16288, follows the contract. What is wrong is the user-facing label and the recovery offer when T3's own usage data contradicts them.
The misleading "Subscription quota exhausted" text originates with Meta. Muse's local journal records the same refusal as error_kind: "tier_limit". That part is being reported to Muse separately.
Suggested direction: keep limitKind and retryable in the schema. When quota is present but latestSubscriptionUsage shows every window under 100%, use neutral wording such as "Muse refused this request", show the provider message and the usage reading, and do not present "Resume at reset" as the fix.
Steps to reproduce
No deterministic repro. It needs a Muse session that Meta refuses with a quota-class error while the subscription window still has room. Here it was a long muse-wonder-full-1.0 thread at about 315k prompt tokens across 885 messages, well under the model's 1,007,997-token context limit. On the same account and window, a one-line muse exec on the same model and route succeeded at 19:17Z, between two refusals of the long thread.
- Run a Muse thread until a turn fails with
turn/completedcarryingerror.quota. - Compare it with the most recent
usage/changedevent in the provider event log. - Look at the failure item title and the recovery banner.
Version
0.1.4-nightly.20261028.3841
Environment
Linux x86_64, Ubuntu 26.04, T3 headless server via t3 serve, Muse Code 1.4.14-R7309.1
Evidence
# provider event log for the thread, native events
[2026-10-29T19:12:55.715Z] usage/changed {"weekly":{"usedPercent":45,...},"window":{"resetsAtMs":1793316262000,"usedPercent":20,"windowDurationMins":300}}
[2026-10-29T19:18:02.479Z] turn/completed {"terminal":"failed","error":{"kind":"modelError","message":"API error 429 [request_id=e59387f3-bc74-41a0-aaa8-594279952249]: Subscription quota exhausted. Your usage window resets at 2026-10-29T23:24:22Z. (rate_limit_error)","quota":{"limitKind":"tierLimit","resetsAtMs":1793316262000},"retryable":false}}
# muse local tracing, same refusal
event="provider_stream.terminal" terminal="failed" reason="rate_limited" http_status=429 request_id="e59387f3-..." bytes_read=0 wire_events_seen=0
# muse usage --json, same minute
{"window":{"resetsAtMs":1793316262000,"usedPercent":20},"weekly":{"usedPercent":45},"reason":null}Refusals of the same shape at 19:12:55Z, 19:18:02Z and 19:31:27Z. Each came back about 5 seconds after the request.
Related issues
#24885 is the same mislabel for Codex and OpenCode. It is not a duplicate: there, Codex discards the upstream reason before T3 sees it, while here Muse delivers a typed limitKind and retryable that T3's schema drops, and T3 already holds a usage report that contradicts the label. #18235, Muse usage never showing in Usage → Limits, is related but different.
Fix applied or workaround
None on the machine. The work moved to a fresh thread on another provider. The blocked thread is still blocked.
Filed by
claude, Opus 5.5, investigating by hand, not via t3 triage
Activity