#17507 · @ChicK00o · opened Mar 14, 2026 at 4:19 PM UTC · last updated Mar 21, 2026 at 2:42 AM UTC
feat(session): add opt-in retry delegation for plugin-controlled fallbacks
Score breakdown
Impact
Clarity
Urgency
Ease Of Review
Guidelines
Readiness
Size
Trust
Traction
Summary
This PR introduces opt-in configuration for session retry handling, allowing plugins to delegate retry logic for provider fallbacks. It also improves nested API error parsing and fixes an isRetryable default, enabling more flexible and robust retry strategies for multi-provider setups.
Description
Issue for this PR
Related to:
- oh-my-opencode PR: https://github.com/code-yeongyu/oh-my-opencode/pull/2570
- Session retry handling improvements for provider fallback chains
Type of change
- [x] New feature
- [x] Bug fix
- [ ] Refactor / code improvement
- [ ] Documentation
What does this PR do?
This PR introduces additive configuration options for session retry handling that enable immediate model switching across providers (Claude → Codex → Alibaba → Z.ai) instead of waiting for quota resets.
⚠️ This is an additive change - existing behavior is unchanged unless users explicitly opt-in via config.
Problem
The default retry behavior waits for rate limit quotas to reset on the same provider. For oh-my-opencode users who want to immediately switch between multiple providers when rate limits are hit, this causes unnecessary delays.
Solution
Two new configuration options in session.retry:
enabled(default:true) - Allows disabling native retry entirelydelegate_to_plugin(default:false) - Allows plugins like oh-my-opencode to handle retries instead of native logic
When delegate_to_plugin: true, native retry is skipped and plugins can implement custom fallback chains (e.g., Claude → Codex → Alibaba → Z.ai).
Additional Improvements
Nested API Error Parsing:
Many providers return rate limit errors in nested JSON structures. The SessionRetry.retryable() function now parses responseBody to detect:
rate_limit_errortype (Anthropic format)too_many_requeststype (OpenAI format)- Nested error structures in
error.error.message
isRetryable Default Fix:
When isRetryable is undefined, it now defaults to true (retryable) instead of non-retryable.
How did you verify your code works?
- [x] All existing tests pass (18 tests)
- [x] Added 3 new tests for nested error structure handling:
recognizes Anthropic rate limit error with responseBodyrecognizes rate limit error with type in responseBodyhandles isRetryable undefined as retryable
- [x] TypeScript type checking passes
- [x] Tested locally with simulated rate limit errors
bun test test/session/retry.test.ts
# 21 pass, 0 fail
Backwards Compatibility
✅ Fully backwards compatible - No behavior changes unless explicitly configured:
- Without config: Native retry works exactly as before
- With
session.retry.delegate_to_plugin: true: Native retry is skipped, plugin handles it - With
session.retry.enabled: false: No retry occurs
Example Configuration
{
"session": {
"retry": {
"enabled": true,
"delegate_to_plugin": true
}
}
}
When delegate_to_plugin is true, oh-my-opencode can immediately switch providers instead of waiting for quota reset.
Related Work
This PR enables the provider blacklist and immediate fallback chain feature in oh-my-opencode: https://github.com/code-yeongyu/oh-my-openagent/pull/2570
Screenshots / recordings
N/A - Backend logic change
Checklist
- [x] I have tested my changes locally
- [x] I have not included unrelated changes in this PR
- [x] All existing tests pass
- [x] New tests added for new functionality
- [x] TypeScript type checking passes
- [x] Changes are backwards compatible
Files Changed
| File | Changes |
|------|---------|
| packages/opencode/src/config/config.ts | Add session.retry config schema with enabled and delegate_to_plugin options |
| packages/opencode/src/session/retry.ts | Parse nested error structures from responseBody, handle isRetryable undefined |
| packages/opencode/src/session/processor.ts | Check retry config before native retry, respect delegate_to_plugin setting |
| packages/opencode/test/session/retry.test.ts | Add 3 new tests for nested error structure handling |
If you do not follow this template your PR will be automatically rejected.
Linked Issues
None.
Comments
No comments.
Changed Files
packages/opencode/src/cli/upgrade.ts
+2−24packages/opencode/src/config/config.ts
+15−0packages/opencode/src/session/processor.ts
+6−1packages/opencode/src/session/retry.ts
+25−2packages/opencode/test/session/retry.test.ts
+46−0