Summary
OpenRouter free-tier keys trigger Invalid openrouter-key-v1 response because the plugin does not handle limit_remaining: null when the API returns no usage limit.
Symptom
Running /quota with a valid OpenRouter free-tier key produces:
OpenRouter: Invalid openrouter-key-v1 response
The key is valid (verified via GET https://openrouter.ai/api/v1/key → HTTP 200), but the plugin rejects it.
Root Cause
In src/lib/quota-providers-remote.ts:684:
(remaining !== undefined && (typeof remaining !== "number" || !Number.isFinite(remaining)))
OpenRouter free-tier API returns:
{ "data": { "usage": 0.106921435, "limit": null, "limit_remaining": null } }
limit_remaining: null (not undefined)
null !== undefined → true
typeof null !== "number" → true
- Condition fails → error message
The plugin already handles limit: null correctly (lines 681-682), but limit_remaining: null is not handled. No test covers this case.
Impact
- OpenRouter free-tier users cannot use the plugin's budget tracking
- False positive error for valid keys
- Plugin appears broken for free-tier users
Proposed Fix
Patch src/lib/quota-providers-remote.ts:684:
// Before
(remaining !== undefined && (typeof remaining !== "number" || !Number.isFinite(remaining)))
// After
(remaining !== null && remaining !== undefined && (typeof remaining !== "number" || !Number.isFinite(remaining)))
Treat null as absent (consistent with limit handling).
Test Coverage
Add test case for free-tier response:
it("accepts OpenRouter free-tier (limit_remaining null)", async () => {
vi.stubGlobal("fetch", vi.fn().mockResolvedValue(
jsonResponse({ data: { usage: 0.1, limit: null, limit_remaining: null } })
));
const result = await fetchRemoteQuotaProvider(source({ format: "openrouter-key-v1" }), "secret");
expect(result.success).toBe(true);
expect(result.entries[0].kind).toBe("spend"); // "Spend" instead of budget
});
Affected Versions
- npm:
@slkiser/opencode-quota@4.8.2 (latest)
- GitHub: main branch (no fix yet)
Reproduction
# Using a free-tier key (limit_remaining: null)
curl https://openrouter.ai/api/v1/key -H "Authorization: Bearer <your-key>"
# → { "data": { "usage": 0.106921435, "limit": null, "limit_remaining": null } }
# Plugin rejects this response with "Invalid openrouter-key-v1 response"
Summary
OpenRouter free-tier keys trigger
Invalid openrouter-key-v1 responsebecause the plugin does not handlelimit_remaining: nullwhen the API returns no usage limit.Symptom
Running
/quotawith a valid OpenRouter free-tier key produces:The key is valid (verified via
GET https://openrouter.ai/api/v1/key→ HTTP 200), but the plugin rejects it.Root Cause
In
src/lib/quota-providers-remote.ts:684:OpenRouter free-tier API returns:
{ "data": { "usage": 0.106921435, "limit": null, "limit_remaining": null } }limit_remaining: null(notundefined)null !== undefined→ truetypeof null !== "number"→ trueThe plugin already handles
limit: nullcorrectly (lines 681-682), butlimit_remaining: nullis not handled. No test covers this case.Impact
Proposed Fix
Patch
src/lib/quota-providers-remote.ts:684:Treat
nullas absent (consistent withlimithandling).Test Coverage
Add test case for free-tier response:
Affected Versions
@slkiser/opencode-quota@4.8.2(latest)Reproduction