What happened?
A Claude subscription/session-limit response can bypass retry.fallbackChains when claude-sdk-oauth uses tokenInjection: "ambient". This is distinct from #505: Claude Agent SDK 0.3.241 returned a result with a successful subtype but an explicit error flag:
{
"type": "result",
"subtype": "success",
"is_error": true,
"api_error_status": 429,
"terminal_reason": "api_error",
"result": "You've hit your session limit · resets 2:50pm (Asia/Seoul)"
}
Senpi treats the turn as successful, so the retry/fallback controller receives no provider error and emits no fallback_applied event. This breaks Claude-primary setups that depend on another provider after the 5-hour limit.
On current main (488d672), sdkFailure() only checks result messages when message.subtype !== "success", while the ambient branch directly yield*s createAttemptMessages(...) without calling sdkFailure().
A local patch that also checks message.is_error === true, preserves message.result for classification, and inspects ambient messages produced FALLBACK_QA_OK plus fallback_applied: claude-sdk-oauth/claude-opus-5 -> openai-codex/gpt-5.6-sol-fast (reason: transient).
Steps to reproduce
- Configure
claude-sdk-oauth with tokenInjection: "ambient" and a fallback chain from claude-opus-5 to another provider.
- Exhaust the Claude CLI 5-hour/session limit.
- Run an isolated print turn:
senpi -ne --model claude-sdk-oauth/claude-opus-5:max -p --no-session --no-tools --no-skills --no-context-files "Return exactly FALLBACK_QA_OK"
- Observe the limit text is surfaced without switching models and no
fallback_applied event appears.
Expected behavior
is_error: true should enter retry/fallback classification even when subtype is success, and the configured fallback model should serve the turn. A regression should cover both this contradictory error result and a normal subtype: success, is_error: false pass-through.
Version
Senpi 2026.8.27; @anthropic-ai/claude-agent-sdk 0.3.241; Windows 11; ambient auth lane
What happened?
A Claude subscription/session-limit response can bypass
retry.fallbackChainswhenclaude-sdk-oauthusestokenInjection: "ambient". This is distinct from #505: Claude Agent SDK 0.3.241 returned a result with a successful subtype but an explicit error flag:{ "type": "result", "subtype": "success", "is_error": true, "api_error_status": 429, "terminal_reason": "api_error", "result": "You've hit your session limit · resets 2:50pm (Asia/Seoul)" }Senpi treats the turn as successful, so the retry/fallback controller receives no provider error and emits no
fallback_appliedevent. This breaks Claude-primary setups that depend on another provider after the 5-hour limit.On current main (
488d672),sdkFailure()only checks result messages whenmessage.subtype !== "success", while the ambient branch directlyyield*screateAttemptMessages(...)without callingsdkFailure().A local patch that also checks
message.is_error === true, preservesmessage.resultfor classification, and inspects ambient messages producedFALLBACK_QA_OKplusfallback_applied: claude-sdk-oauth/claude-opus-5 -> openai-codex/gpt-5.6-sol-fast(reason: transient).Steps to reproduce
claude-sdk-oauthwithtokenInjection: "ambient"and a fallback chain fromclaude-opus-5to another provider.fallback_appliedevent appears.Expected behavior
is_error: trueshould enter retry/fallback classification even whensubtypeissuccess, and the configured fallback model should serve the turn. A regression should cover both this contradictory error result and a normalsubtype: success, is_error: falsepass-through.Version
Senpi 2026.8.27; @anthropic-ai/claude-agent-sdk 0.3.241; Windows 11; ambient auth lane