Hmbown/CodeWhale · error · Error
Runtime API request failed (${status}): ${message}
Error message
Runtime API request failed (${status}): ${message} What it means
The telegram bridge's event pump fetches `${config.runtimeUrl}/v1/threads/{threadId}/events?since_seq=`; when response.ok is false, readJsonSafe parses the body and compactRuntimeError formats it as `Runtime API request failed (${status}): ${message}`, preferring body.error.message, then body.message, else the raw body. The status and embedded message say exactly what the Codewhale runtime rejected. The runtime URL comes from CODEWHALE_RUNTIME_URL/DEEPSEEK_RUNTIME_URL (default http://127.0.0.1:7878) and auth from CODEWHALE_RUNTIME_TOKEN/DEEPSEEK_RUNTIME_TOKEN.
Source
Thrown at integrations/telegram-bridge/src/index.mjs:614
}
};
const typingTimer = setInterval(() => {
void tickTyping();
}, TYPING_INTERVAL_MS);
typingTimer.unref?.();
try {
void tickTyping();
const response = await fetch(
`${config.runtimeUrl}/v1/threads/${encodeURIComponent(threadId)}/events?since_seq=${sinceSeq}`,
{
headers: authHeaders(),
signal: controller.signal
}
);
if (!response.ok) {
const body = await readJsonSafe(response);
throw new Error(compactRuntimeError(response.status, body));
}
for await (const event of readSse(response)) {
if (!event.data) continue;
const record = JSON.parse(event.data);
latestSeq = Math.max(latestSeq, Number(record.seq || 0));
await flushLastSeq(false);
if (turnId && record.turn_id && record.turn_id !== turnId) continue;
const lifecycleStatus =
record.event === "turn.lifecycle"
? record.payload?.turn?.status || record.payload?.status
: null;
const stopTypingEvent =
record.event === "turn.completed" ||
["failed", "canceled", "interrupted"].includes(lifecycleStatus);
if (typingPaused && record.event !== "approval.required" && !stopTypingEvent) {
typingPaused = false;View on GitHub (pinned to 8880682c63)
Solutions
- Confirm the runtime is reachable at CODEWHALE_RUNTIME_URL from the bridge host (curl the /v1/threads endpoint with the same auth headers)
- Re-sync the token: export CODEWHALE_RUNTIME_TOKEN to the current value the runtime accepts
- GET /v1/threads/{threadId} to confirm the thread exists; recreate it if it was pruned
- For 5xx, read the runtime's own message in the parentheses and check runtime logs — the bridge is only the messenger
Example fix
# before: runtime moved to port 7879 export CODEWHALE_RUNTIME_URL=http://127.0.0.1:7878 # after export CODEWHALE_RUNTIME_URL=http://127.0.0.1:7879
Defensive patterns
Strategy: retry
Validate before calling
const probe = await fetch(
`${config.runtimeUrl}/v1/threads/${encodeURIComponent(threadId)}`,
{ headers: authHeaders() }
);
if (!probe.ok) {
console.error(`runtime preflight failed: ${probe.status}`);
process.exit(2);
} Try / catch
try {
await streamThreadEvents(threadId, sinceSeq);
} catch (error) {
const status = Number(error.message.match(/Runtime API request failed \((\d+)\)/)?.[1]);
if (status >= 500) { await backoffAndRetry(); return; }
if (status === 401 || status === 404) { console.error('config drift — fix token/thread'); process.exit(2); }
throw error;
} Prevention
- Preflight the runtime URL and token before entering the SSE loop
- Treat 401/404 as config drift — alert and stop rather than retry
- Log threadId with every failure so 404s trace back to pruned threads
When it happens
Trigger: 401 when the runtime token does not match; 404 when threadId no longer exists on the runtime; 5xx when the runtime behind CODEWHALE_RUNTIME_URL is unhealthy; a wrong port or stale URL in the env.
Common situations: Runtime token rotated in the TUI while the bridge keeps the old env value; runtime moved to a different port; idle chat's thread evicted by retention so the SSE resume 404s.
Related errors
- Runtime API request failed (${status}): ${message}
- Runtime API request failed (${status}): ${message}
- Cloudflare SQL request failed (${response.status}): ${body}
- Could not inspect GitHub Release ${tag}: ${detail}
- DeepSeek ${res.status}: ${text}
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/22ef47d91f1f0c5e.
Report an issue: GitHub.