Hmbown/CodeWhale · error · Error

Runtime API request failed (${status}): ${message}

Error message

Runtime API request failed (${status}): ${message}

What it means

bridge-core's runtimeJson() throws this whenever the codewhale runtime HTTP API answers non-2xx. compactRuntimeError() extracts body.error.message (or body.message) so the suffix is the server's own explanation; the number in parentheses is the HTTP status, e.g. `Runtime API request failed (401): invalid token`.

Source

Thrown at integrations/bridge-core/src/lib.mjs:465

}

export function createRuntimeClient({ runtimeUrl, runtimeToken }) {
  function authHeaders() {
    return { authorization: `Bearer ${runtimeToken}` };
  }

  async function runtimeJson(route, options = {}) {
    const response = await fetch(`${runtimeUrl}${route}`, {
      method: options.method || "GET",
      headers: {
        ...(options.auth === false ? {} : authHeaders()),
        ...(options.body ? { "content-type": "application/json" } : {})
      },
      body: options.body ? JSON.stringify(options.body) : undefined
    });
    const body = await readJsonSafe(response);
    if (!response.ok) {
      throw new Error(compactRuntimeError(response.status, body));
    }
    return body;
  }

  return { runtimeJson, authHeaders };
}

export function compactRuntimeError(status, body) {
  const message =
    body?.error?.message ||
    body?.message ||
    (typeof body === "string" ? body : JSON.stringify(body));
  return `Runtime API request failed (${status}): ${message}`;
}

export function latestRunningTurn(detail) {
  const turns = Array.isArray(detail?.turns) ? detail.turns : [];
  for (let index = turns.length - 1; index >= 0; index -= 1) {

View on GitHub (pinned to 8880682c63)

Solutions

  1. Verify the runtime is up and the bridge's runtimeUrl/port matches it
  2. Regenerate and re-pass the auth token env after the runtime restarts
  3. Read the embedded server message - it usually names the exact bad field or auth problem
  4. Health-check the runtime before dispatching traffic

Example fix

// before
await runtimeJson('/v1/threads', { method: 'POST', body: { prompt } });

// after - check liveness first, fail with a clearer error
const probe = await fetch(runtimeUrl, { method: 'HEAD' }).catch(() => null);
if (!probe || !probe.ok) {
  throw new Error('codewhale runtime unreachable at ' + runtimeUrl);
}
await runtimeJson('/v1/threads', { method: 'POST', body: { prompt } });
Defensive patterns

Strategy: try-catch

Validate before calling

const probe = await fetch(runtimeUrl, { method: 'HEAD' }).catch(() => null);
if (!probe || !probe.ok) {
  throw new Error('codewhale runtime unreachable at ' + runtimeUrl);
}

Try / catch

try {
  return await runtimeJson(route, options);
} catch (err) {
  const m = /^Runtime API request failed \((\d+)\)/.exec(err.message);
  if (m && m[1] === '401') { await refreshRuntimeAuth(); return retryOnce(); }
  if (m && m[1] === '404') { throw new Error('runtime URL misrouted: ' + runtimeUrl + route); }
  throw err;
}

Prevention

When it happens

Trigger: 401 when the bridge's auth headers do not match the runtime session; 404 when runtimeUrl points at the wrong port/path; 400 when the JSON body fails server-side validation; 5xx during runtime shutdown or crash.

Common situations: CODEWHALE_RUNTIME_URL stale after a restart (new port); token env copied from an older `codewhale web` run; a proxy in front of the runtime rewriting errors.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/a6cdd0b95957da41. Report an issue: GitHub.