Hmbown/CodeWhale · error · RuntimeApiError
Runtime API request failed (${response.status}) for ${method
Error message
Runtime API request failed (${response.status}) for ${method} ${path} What it means
The generic non-2xx failure of CodeWhaleRuntimeClient: any error response that is not a capability 404/405/501 becomes RuntimeApiError with the status embedded in the message. The error exposes .status, .method, .path and up to 4096 bytes of the response .body, so the real cause is almost always readable there. Routes that never set a capability — listFleetRuns, getFleetRun, listFleetWorkers, getFleetWorker, interruptWorker, stopWorker, restartWorker, stopFleetRun — always fail with this class (even 404s).
Source
Thrown at npm/runtime-sdk/index.js:162
headers.set("content-type", "application/json");
init.body = JSON.stringify(options.body);
}
const response = await this.fetchImpl(new URL(path, this.baseUrl), init);
if (response.ok) {
return response;
}
const body = await readErrorBody(response);
const errorOptions = { status: response.status, method, path, body };
if (options.capability && [404, 405, 501].includes(response.status)) {
throw new RuntimeCapabilityError(
options.capability,
`Runtime API capability '${options.capability}' is not available at ${method} ${path}`,
errorOptions,
);
}
throw new RuntimeApiError(
`Runtime API request failed (${response.status}) for ${method} ${path}`,
errorOptions,
);
}
}
export function createRuntimeClient(options = {}) {
return new CodeWhaleRuntimeClient(options);
}
function normalizeBaseUrl(value) {
return value.endsWith("/") ? value : `${value}/`;
}
function segment(value) {
if (value === null || value === undefined || String(value).trim() === "") {
throw new TypeError("Runtime API path segment must be a non-empty value");
}View on GitHub (pinned to 8880682c63)
Solutions
- Inspect err.status and err.body first — the runtime's JSON error names the actual problem (auth, unknown id, invalid input)
- Pass a token if the runtime requires it: createRuntimeClient({ baseUrl, token })
- Verify the id still exists on this runtime via listFleetRuns() / listFleetWorkers(runId) before acting on it
- For err.status >= 500 check runtime logs and health before retrying; do not blind-retry a 4xx
Example fix
// before
const run = await client.getFleetRun(runId); // RuntimeApiError (404) crashes the caller
// after
import { RuntimeApiError } from "@codewhale/runtime-sdk";
try {
const run = await client.getFleetRun(runId);
} catch (error) {
if (error instanceof RuntimeApiError && error.status === 404) {
return null; // run no longer exists on this runtime instance
}
throw error;
} Defensive patterns
Strategy: try-catch
Validate before calling
async function fleetRunExists(client, runId) {
const runs = await client.listFleetRuns();
const events = Array.isArray(runs) ? runs : (runs?.runs ?? runs?.items ?? []);
return events.some((run) => run?.id === runId);
} Type guard
import { RuntimeApiError } from "@codewhale/runtime-sdk";
function isRuntimeApiError(error) {
return error instanceof RuntimeApiError || error?.name === "RuntimeApiError";
} Try / catch
try {
return await client.getFleetRun(runId);
} catch (error) {
if (isRuntimeApiError(error)) {
if (error.status === 404) return null;
if (error.status === 401 || error.status === 403) throw new Error(`Auth rejected by runtime: ${error.body}`);
if (error.status >= 500) throw new Error(`Runtime unhealthy (${error.status}); check runtime logs`);
}
throw error;
} Prevention
- Always inspect err.status and err.body before deciding retry vs fail — the runtime's JSON message names the cause
- Configure the token at client construction instead of assuming an open runtime
- Treat ids as instance-scoped: refetch via listFleetRuns/listFleetWorkers after a runtime restart
- Wrap fleet calls in one shared error translator so 401/404/5xx get consistent handling across your app
When it happens
Trigger: GET /v1/fleet/runs returning 401 because no token was configured; GET /v1/fleet/runs/{id} or /v1/fleet/workers/{id} with an unknown or deleted id returning 404; POST stop/interrupt/restart on a dead worker returning 409; POST /v1/fleet/runs with an invalid spec returning 400; runtime crash returning 500.
Common situations: Forgetting options.token when the runtime enforces auth; reusing a runId/workerId from a previous runtime instance whose state was wiped on restart; the runtime process crashed or OOMed behind the port; network-level 502/504 from a proxy on baseUrl.
Related errors
- Runtime API capability '${options.capability}' is not availa
- Runtime API path segment must be a non-empty value
- expected application/x-www-form-urlencoded
- invalid Content-Length
- payload too large
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/445a57e807522ca4.
Report an issue: GitHub.