can1357/oh-my-pi · error · Error

Usage reserve reached for ${primary.model.provider}/${primar

Error message

Usage reserve reached for ${primary.model.provider}/${primary.model.id}; reserve policy is fail-closed.

What it means

When the provider's usage health reports "reserve" (remaining usage has dropped into the reserve threshold) and usageReservePolicy is "fail-closed", the SDK refuses to start the session rather than risk mid-session exhaustion.

Source

Thrown at packages/coding-agent/src/sdk.ts:2461

							provider: primary.model.provider,
							model: primary.model.id,
							error: String(error),
						});
					}
					if (usageHealth?.state === "depleted") {
						if (usageReservePolicy === "fail-closed") {
							throw new Error(
								`Usage depleted for ${primary.model.provider}/${primary.model.id}; reserve policy is fail-closed.`,
							);
						}
						if (modelFallbackEnabled) {
							usageFallbackTriggered = true;
							continue;
						}
					}
					if (usageHealth?.state === "reserve") {
						if (usageReservePolicy === "fail-closed") {
							throw new Error(
								`Usage reserve reached for ${primary.model.provider}/${primary.model.id}; reserve policy is fail-closed.`,
							);
						}
						if (
							modelFallbackEnabled &&
							(usageReservePolicy === "auto" || (!options.hasUI && !options.deferUsageReserveConfirmation))
						) {
							usageFallbackTriggered = true;
							continue;
						}
					}
				}
				let selectedModel = primary.model;
				let selectedThinkingLevel = primary.thinkingLevel;
				let selectedExplicitThinkingLevel = primary.explicitThinkingLevel;
				// A chain entry without its own `:level` suffix inherits the
				// unavailable primary's configured thinking level, matching
				// runtime fallback-chain semantics.

View on GitHub (pinned to 9690622007)

Solutions

  1. Restore provider quota/credits to move usage out of the reserve state
  2. Set usageReservePolicy to "auto" or "warn" to allow fallback/continuation
  3. Enable modelFallbackEnabled (or allow usage-reserve confirmation via hasUI/deferUsageReserveConfirmation settings) so the session can switch models

Example fix

// before
await createAgentSession({ usageReservePolicy: "fail-closed", hasUI: false, ... });
// after
await createAgentSession({ usageReservePolicy: "auto", modelFallbackEnabled: true, ... });
Defensive patterns

Strategy: fallback

Validate before calling

const health = await getUsageHealth(primaryModel);
if (health?.state === "reserve") console.warn("provider usage in reserve threshold");

Type guard

null

Try / catch

try {
  session = await createAgentSession(options);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Usage reserve reached")) {
    session = await createAgentSession({ ...options, usageReservePolicy: "auto", modelFallbackEnabled: true });
  } else throw err;
}

Prevention

When it happens

Trigger: createAgentSession with usageReservePolicy "fail-closed" while primary model provider usage state is "reserve" and fallback conditions (modelFallbackEnabled with "auto" or headless confirmation settings) are not met.

Common situations: Provider balance close to exhaustion; strict CI policy configured; interactive UI present but deferUsageReserveConfirmation set so automatic fallback is skipped.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/c8b87efba2823b1e. Report an issue: GitHub.