Summary
startGatewayModelPricingRefresh crashes with RangeError: Maximum call stack size exceeded when openrouter/auto is configured as the primary model.
Versions
- OpenClaw 2026.3.22 (4dcc39c)
- Node 22, Linux (Ubuntu 24.04)
Config (relevant part)
{
"agents": {
"defaults": {
"model": { "primary": "openrouter/auto" }
}
}
}
Log
[model-pricing] pricing bootstrap failed: RangeError: Maximum call stack size exceeded
Root Cause
buildOpenRouterExactCandidates in src/gateway/model-pricing-cache.ts recurses infinitely for OpenRouter-native models.
Trace:
collectConfiguredModelPricingRefs normalizes openrouter/auto → { provider: "openrouter", model: "openrouter/auto" } (correct — native model keeps prefix)
buildOpenRouterExactCandidates({ provider: "openrouter", model: "openrouter/auto" }) checks WRAPPER_PROVIDERS.has("openrouter") && "openrouter/auto".includes("/") → true
parseModelRef("openrouter/auto") → { provider: "openrouter", model: "openrouter/auto" } (same ref — fixed point)
- Recursive call with identical input → infinite loop → stack overflow
The issue is that parseModelRef for OpenRouter-native models returns the model ID with the provider prefix intact (openrouter/auto not auto), so the "unwrap nested provider" recursion never terminates.
Suggested Fix
Add a recursion guard — either a depth limit or a seen set:
function buildOpenRouterExactCandidates(ref: ModelRef, depth = 0): string[] {
if (depth > 5) return [];
// ... existing code ...
// Change recursive call:
for (const candidate of buildOpenRouterExactCandidates(nestedRef, depth + 1)) ...
}
Impact
- Gateway starts and runs fine — the error is caught and logged as a warning
- Pricing cache stays empty →
usage.cost in session logs is undefined for models routed through openrouter/auto
- Does NOT affect plugins that use OpenRouter API directly for cost tracking
Repro
Set agents.defaults.model.primary to openrouter/auto and restart gateway.
Summary
startGatewayModelPricingRefreshcrashes withRangeError: Maximum call stack size exceededwhenopenrouter/autois configured as the primary model.Versions
Config (relevant part)
{ "agents": { "defaults": { "model": { "primary": "openrouter/auto" } } } }Log
Root Cause
buildOpenRouterExactCandidatesinsrc/gateway/model-pricing-cache.tsrecurses infinitely for OpenRouter-native models.Trace:
collectConfiguredModelPricingRefsnormalizesopenrouter/auto→{ provider: "openrouter", model: "openrouter/auto" }(correct — native model keeps prefix)buildOpenRouterExactCandidates({ provider: "openrouter", model: "openrouter/auto" })checksWRAPPER_PROVIDERS.has("openrouter") && "openrouter/auto".includes("/")→ trueparseModelRef("openrouter/auto")→{ provider: "openrouter", model: "openrouter/auto" }(same ref — fixed point)The issue is that
parseModelReffor OpenRouter-native models returns the model ID with the provider prefix intact (openrouter/autonotauto), so the "unwrap nested provider" recursion never terminates.Suggested Fix
Add a recursion guard — either a depth limit or a
seenset:Impact
usage.costin session logs is undefined for models routed throughopenrouter/autoRepro
Set
agents.defaults.model.primarytoopenrouter/autoand restart gateway.