Hmbown/CodeWhale · error · RuntimeCapabilityError
Runtime API capability '${options.capability}' is not availa
Error message
Runtime API capability '${options.capability}' is not available at ${method} ${path} What it means
Thrown as RuntimeCapabilityError by CodeWhaleRuntimeClient (npm/runtime-sdk) when a capability-tagged fleet endpoint answers HTTP 404, 405, or 501. It means the runtime server behind baseUrl (default http://127.0.0.1:7878) does not implement that capability, most often because the runtime binary and the SDK are at different versions. The error carries .capability, .status, .method, .path and the response .body for diagnosis. Only createFleetRun (fleet_run_create), startFleetRun (fleet_run_start), replayFleetEvents (fleet_event_replay), and the fleetEvents stream (fleet_event_stream) set a capability; other routes surface as plain RuntimeApiError.
Source
Thrown at npm/runtime-sdk/index.js:156
headers.set("accept", options.accept ?? "application/json");
if (this.token) {
headers.set("authorization", `Bearer ${this.token}`);
}
const init = { method, headers };
if (options.body !== undefined) {
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}/`;View on GitHub (pinned to 8880682c63)
Solutions
- Read err.capability, err.status and err.path, then bring the Codewhale runtime to a version that implements that capability (align runtime and SDK versions)
- Confirm createRuntimeClient({ baseUrl }) points directly at the runtime port (default 127.0.0.1:7878) and no proxy strips or rewrites /v1/fleet/* paths
- Reproduce manually with the method/path from the message and inspect the response body to see whether a gateway or the runtime itself answered
- If the capability is optional in your integration, catch RuntimeCapabilityError and degrade gracefully instead of failing the whole run
Example fix
// before
const run = await client.createFleetRun(spec); // crashes with RuntimeCapabilityError against an old runtime
// after
import { RuntimeCapabilityError } from "@codewhale/runtime-sdk";
try {
const run = await client.createFleetRun(spec);
} catch (error) {
if (error instanceof RuntimeCapabilityError) {
console.error(
`Runtime lacks ${error.capability} (HTTP ${error.status} on ${error.method} ${error.path}); upgrade the runtime binary to match this SDK`,
);
}
throw error;
} Defensive patterns
Strategy: try-catch
Validate before calling
async function runtimeHasFleetApi(client) {
const response = await client.fetchImpl(new URL("/v1/fleet/runs", client.baseUrl), {
method: "GET",
headers: { accept: "application/json" },
});
return response.ok || response.status === 405;
} Type guard
import { RuntimeCapabilityError } from "@codewhale/runtime-sdk";
function isRuntimeCapabilityError(error) {
return error instanceof RuntimeCapabilityError || error?.name === "RuntimeCapabilityError";
} Try / catch
try {
await client.startFleetRun(runId);
} catch (error) {
if (isRuntimeCapabilityError(error) && [404, 405, 501].includes(error.status)) {
// capability unavailable: upgrade the runtime or disable this code path
return handleUnsupportedCapability(error.capability);
}
throw error;
} Prevention
- Pin the SDK and the runtime binary to the same release so capability endpoints exist on both sides
- Probe /v1/fleet/runs once at startup and refuse to submit fleet work when the probe fails
- Log error.capability, error.status and error.path whenever this fires to identify the missing endpoint immediately
- Keep baseUrl pointed straight at the runtime port (127.0.0.1:7878) unless a proxy is verified to pass /v1/fleet/* through
When it happens
Trigger: POST /v1/fleet/runs, POST /v1/fleet/runs/{id}/start, GET|POST /v1/fleet/runs/{id}/events/replay, or GET /v1/fleet/runs/{id}/events (accept: text/event-stream) responding 404, 405, or 501 while options.capability is set in #rawRequest.
Common situations: SDK upgraded ahead of the runtime binary (or an old runtime pinned in Docker/CI); baseUrl pointing at a proxy or gateway that rewrites fleet paths into 404s; a runtime build with the fleet API disabled or compiled out; middleware answering 501 for unknown methods.
Related errors
- Runtime API request failed (${response.status}) for ${method
- 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/85e6e2f69f8a91c0.
Report an issue: GitHub.