decolua/9router · error
Kilo API returned ${res.status}
Error message
Kilo API returned ${res.status} What it means
The kilo free-models route fetches KILO_MODELS_URL with a 10s timeout and expects a 2xx JSON response. If res.ok is false (any 4xx/5xx from the Kilo upstream), the route surfaces the upstream status in this error instead of trying to parse a non-JSON error body.
Source
Thrown at src/app/api/providers/kilo/free-models/route.js:25
let cacheTimestamp = 0;
const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
export async function GET() {
const now = Date.now();
// Return cached result if still valid
if (cachedModels && now - cacheTimestamp < CACHE_TTL_MS) {
return NextResponse.json({ models: cachedModels, cached: true });
}
try {
const res = await fetch(KILO_MODELS_URL, {
headers: { "Accept": "application/json" },
signal: AbortSignal.timeout(10000),
});
if (!res.ok) {
throw new Error(`Kilo API returned ${res.status}`);
}
const json = await res.json();
const allModels = json.data || [];
const freeModels = allModels
.filter((m) => m.isFree === true)
.map((m) => ({
id: m.id,
name: m.name,
isFree: true,
context_length: m.context_length || 0,
}));
cachedModels = freeModels;
cacheTimestamp = now;
return NextResponse.json({ models: freeModels, cached: false });View on GitHub (pinned to 90b52e06ff)
Solutions
- Retry later if the Kilo API is having an outage (5xx).
- Check the returned status in the message: 401/403 means auth/blocking — verify network access to the Kilo endpoint from this machine.
- Verify KILO_MODELS_URL is still valid upstream and update the constant if Kilo moved the endpoint.
- Reduce polling frequency if hitting 429 rate limits.
Defensive patterns
Strategy: retry
Try / catch
try {
const models = await fetchFreeModels();
} catch (e) {
if (e.message.startsWith("Kilo API returned")) {
const status = parseInt(e.message.match(/\d+$/)?.[0], 10);
if (status >= 500 || status === 429) await delay(backoff).then(retry);
else console.error("Kilo upstream rejected the request:", status);
} else throw e;
} Prevention
- Retry with backoff on 429/5xx only
- Cache the free-models list instead of polling repeatedly
- Check Kilo API status/docs when the status is 404 (endpoint moved)
- Verify outbound network/proxy access to the Kilo endpoint
When it happens
Trigger: GET /api/providers/kilo/free-models while the Kilo models API returns 401/403 (auth required), 404 (endpoint moved), 429 (rate limited), or 5xx outage; also when a proxy/firewall intercepts with an error status.
Common situations: Kilo API is down or geo-blocked, the hard-coded KILO_MODELS_URL changed upstream, corporate proxy returns 403, or rate limiting from repeated polling.
Related errors
- Upstream error (${res.status})
- Edge TTS voices fetch failed: ${res.status}
- Google TTS failed: ${res.status}
- MiniMax TTS error (${res.status})
- OpenAI TTS failed: ${res.status}
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/f0b2a4563e266fb6.
Report an issue: GitHub.