Hmbown/CodeWhale · error
${compactRuntimeError(response.status, result)}
Error message
${compactRuntimeError(response.status, result)} What it means
runtimeJson is the Weixin bridge's general-purpose JSON fetch helper for the runtime API: it builds the request, reads the JSON body via readJsonSafe, and throws compactRuntimeError(response.status, result) whenever the HTTP status is not OK. Any non-2xx runtime response on any method/subPath funnels through this single error, carrying the status and server-provided error details.
Solutions
- Parse the status/message: fix credentials (401/403), fix the URL/subPath (404), or fix the request payload (400).
- Check runtime server logs for 5xx responses and restart/repair the runtime service.
- Re-authenticate so authHeaders() carries a fresh valid token.
Example fix
// before
runtimeJson("POST", "/turns", body) // -> Error: 401 ...
// after: refresh token before the call
const token = await refreshRuntimeToken();
runtimeJson("POST", "/turns", body, token); Defensive patterns
Strategy: try-catch
Validate before calling
// Probe the runtime before issuing real calls:
const res = await fetch(`${config.runtimeUrl}/health`);
if (!res.ok) throw new Error(`Runtime not ready: HTTP ${res.status}`); Try / catch
try {
const result = await runtimeJson("POST", "/turns", body);
} catch (err) {
if (/^40[13]/.test(err.message)) {
await reauthenticate();
} else if (/^404/.test(err.message)) {
console.error("Endpoint not found: check runtimeUrl and runtime version");
} else if (/^5\d\d/.test(err.message)) {
await retryWithBackoff();
} else {
throw err;
}
} Prevention
- Centralize all runtime calls through runtimeJson (already the case) so error handling is uniform.
- Keep tokens fresh relative to runtime restarts; re-auth on any 401.
- Validate request bodies client-side to avoid 400s.
- Version-check the runtime on startup to catch endpoint drift early.
When it happens
Trigger: Any runtimeJson call (GET/POST to config.runtimeUrl + subPath) where response.ok is false — invalid auth for protected endpoints, wrong subPath yielding 404, or a 5xx from the runtime process.
Common situations: Misconfigured runtimeUrl base, stale auth token after a runtime restart, calling an endpoint that does not exist in the deployed runtime version, or runtime returning 500 on a malformed request body.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- ${compactRuntimeError(response.status, body)}
- ${compactRuntimeError(response.status, body)}
- ${compactRuntimeError(response.status, body)}
- DeepSeek
- detail || ("HTTP " + res.status)
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/d91fbb33a2cd22fb.
Report an issue: GitHub.
Appendix: source
Thrown at integrations/weixin-bridge/src/index.mjs:208
};
}
async function readJsonSafe(response) {
try {
return await response.json();
} catch {
return null;
}
}
async function runtimeJson(subPath, { method = "GET", body = null, auth = true } = {}) {
const url = `${config.runtimeUrl}${subPath}`;
const options = { method, headers: auth ? authHeaders() : {} };
if (body) options.body = JSON.stringify(body);
const response = await fetch(url, options);
const result = await readJsonSafe(response);
if (!response.ok) {
throw new Error(compactRuntimeError(response.status, result));
}
return result;
}
async function* readSse(response) {
let buffer = "";
for await (const chunk of response.body) {
buffer += new TextDecoder().decode(chunk, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop() || "";
for (const line of lines) {
const trimmed = line.trim();
if (!trimmed) continue;
if (trimmed.startsWith("data:")) {
yield { data: trimmed.slice(5).trim() };
} else if (trimmed.startsWith("event:")) {
yield { event: trimmed.slice(6).trim() };
} else if (trimmed.startsWith("id:")) {View on GitHub (pinned to 433685b202)