Problem
The /inference/openrouter/chat endpoint throws an unhandled "e is not iterable" error, likely from destructuring or iterating over a malformed OpenRouter API response.
Evidence from production logs (2026-03-03)
2026-03-03T01:01:46 | /inference/openrouter/chat | Unhandled error | e is not iterable
Root cause (likely)
OpenRouter occasionally returns non-standard response shapes (missing choices array, error objects instead of completions, etc.). The code likely does something like for (const choice of response.choices) without checking that choices exists and is iterable.
Fix
Add defensive checks before iterating over OpenRouter response fields:
if (!response.choices || !Array.isArray(response.choices)) {
// return structured error instead of throwing
}
Additional: invalid model ID errors
Also from logs (2026-02-26), callers are passing x-ai/grok-4.1-mini which OpenRouter rejects. Consider:
- Validating model IDs against a known list before forwarding to OpenRouter
- Returning a clear 400 error instead of proxying OpenRouter's raw error
Priority
Medium — not currently recurring but will bite again with any OpenRouter API change.
Problem
The
/inference/openrouter/chatendpoint throws an unhandled"e is not iterable"error, likely from destructuring or iterating over a malformed OpenRouter API response.Evidence from production logs (2026-03-03)
Root cause (likely)
OpenRouter occasionally returns non-standard response shapes (missing
choicesarray, error objects instead of completions, etc.). The code likely does something likefor (const choice of response.choices)without checking thatchoicesexists and is iterable.Fix
Add defensive checks before iterating over OpenRouter response fields:
Additional: invalid model ID errors
Also from logs (2026-02-26), callers are passing
x-ai/grok-4.1-miniwhich OpenRouter rejects. Consider:Priority
Medium — not currently recurring but will bite again with any OpenRouter API change.