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

  1. Inspect err.status and err.body first — the runtime's JSON error names the actual problem (auth, unknown id, invalid input)
  2. Pass a token if the runtime requires it: createRuntimeClient({ baseUrl, token })
  3. Verify the id still exists on this runtime via listFleetRuns() / listFleetWorkers(runId) before acting on it
  4. 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

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


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