{"record":{"id":"445a57e807522ca4","repo":"Hmbown/CodeWhale","slug":"runtime-api-request-failed-response-status-fo","errorCode":null,"errorMessage":"Runtime API request failed (${response.status}) for ${method} ${path}","messagePattern":"Runtime API request failed \\((.+?)\\) for (.+?) (.+?)","errorType":"exception","errorClass":"RuntimeApiError","httpStatus":null,"severity":"error","filePath":"npm/runtime-sdk/index.js","lineNumber":162,"sourceCode":"      headers.set(\"content-type\", \"application/json\");\n      init.body = JSON.stringify(options.body);\n    }\n\n    const response = await this.fetchImpl(new URL(path, this.baseUrl), init);\n    if (response.ok) {\n      return response;\n    }\n\n    const body = await readErrorBody(response);\n    const errorOptions = { status: response.status, method, path, body };\n    if (options.capability && [404, 405, 501].includes(response.status)) {\n      throw new RuntimeCapabilityError(\n        options.capability,\n        `Runtime API capability '${options.capability}' is not available at ${method} ${path}`,\n        errorOptions,\n      );\n    }\n    throw new RuntimeApiError(\n      `Runtime API request failed (${response.status}) for ${method} ${path}`,\n      errorOptions,\n    );\n  }\n}\n\nexport function createRuntimeClient(options = {}) {\n  return new CodeWhaleRuntimeClient(options);\n}\n\nfunction normalizeBaseUrl(value) {\n  return value.endsWith(\"/\") ? value : `${value}/`;\n}\n\nfunction segment(value) {\n  if (value === null || value === undefined || String(value).trim() === \"\") {\n    throw new TypeError(\"Runtime API path segment must be a non-empty value\");\n  }","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/npm/runtime-sdk/index.js#L144-L180","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nconst run = await client.getFleetRun(runId); // RuntimeApiError (404) crashes the caller\n\n// after\nimport { RuntimeApiError } from \"@codewhale/runtime-sdk\";\ntry {\n  const run = await client.getFleetRun(runId);\n} catch (error) {\n  if (error instanceof RuntimeApiError && error.status === 404) {\n    return null; // run no longer exists on this runtime instance\n  }\n  throw error;\n}","handlingStrategy":"try-catch","validationCode":"async function fleetRunExists(client, runId) {\n  const runs = await client.listFleetRuns();\n  const events = Array.isArray(runs) ? runs : (runs?.runs ?? runs?.items ?? []);\n  return events.some((run) => run?.id === runId);\n}","typeGuard":"import { RuntimeApiError } from \"@codewhale/runtime-sdk\";\nfunction isRuntimeApiError(error) {\n  return error instanceof RuntimeApiError || error?.name === \"RuntimeApiError\";\n}","tryCatchPattern":"try {\n  return await client.getFleetRun(runId);\n} catch (error) {\n  if (isRuntimeApiError(error)) {\n    if (error.status === 404) return null;\n    if (error.status === 401 || error.status === 403) throw new Error(`Auth rejected by runtime: ${error.body}`);\n    if (error.status >= 500) throw new Error(`Runtime unhealthy (${error.status}); check runtime logs`);\n  }\n  throw error;\n}","preventionTips":["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"],"tags":["runtime-api","http","sdk","error-handling","fleet"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}