Hmbown/CodeWhale · error · RuntimeCapabilityError
thread_event_progress
thread_event_progress
Error message
Runtime does not support thread replay progress
What it means
When includeProgress is requested, threadEvents() checks the x-codewhale-event-progress response header. If the runtime does not advertise progress support (header is not "1"), it cancels the stream and throws RuntimeCapabilityError with code thread_event_progress and status 501. This means the connected runtime version does not implement thread replay progress markers.
Solutions
- Upgrade the Codewhale runtime to a version supporting thread replay progress.
- Drop includeProgress: true and consume the stream without progress markers.
- Feature-detect first: catch RuntimeCapabilityError with code 'thread_event_progress' and retry without the flag.
Example fix
// before
for await (const ev of client.threadEvents(id, { includeProgress: true })) handle(ev);
// after
async function replay(id, wantProgress) {
try {
for await (const ev of client.threadEvents(id, { includeProgress: wantProgress })) handle(ev);
} catch (err) {
if (err?.code === "thread_event_progress") return replay(id, false);
throw err;
}
} Defensive patterns
Strategy: fallback
Try / catch
async function replay(id, wantProgress = true) { try { for await (const ev of client.threadEvents(id, { includeProgress: wantProgress })) handle(ev); } catch (err) { if (err?.code === "thread_event_progress") return replay(id, false); throw err; } } Prevention
- Check runtime release notes for thread_event_progress support before using includeProgress.
- Implement automatic degradation to non-progress replay in shared stream helpers.
- Keep runtime and SDK versions aligned in deployment manifests.
When it happens
Trigger: client.threadEvents(id, { includeProgress: true }) against a runtime whose /v1/threads/:id/events endpoint omits x-codewhale-event-progress: 1.
Common situations: Older runtime deployed in staging/production while the client was built against a newer one; connecting a local dev SDK to a minimal or third-party runtime implementation.
Related errors
- ${options.capability}
- Anthropic stream error
- Antigravity cloud-code SSE is not JSON
- Antigravity cloud-code SSE shape is unproven; failing closed
- Chat Completions stream closed before [DONE] or…
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/c61cedb2d61343e3.
Report an issue: GitHub.
Appendix: source
Thrown at npm/runtime-sdk/index.js:149
if (value === undefined) continue;
if (!Number.isSafeInteger(value) || value < 0) throw new TypeError(`${key} must be a nonnegative safe integer`);
query.set(key, String(value));
}
if (options.includeProgress !== undefined && typeof options.includeProgress !== "boolean")
throw new TypeError("includeProgress must be a boolean");
if (options.includeProgress) query.set("progress", "true");
const path = `/v1/threads/${segment(threadId)}/events?${query}`;
const response = await this.#rawRequest(path, {
method: "GET", capability: "thread_event_stream", accept: "text/event-stream",
signal: options.signal, redirect: "error",
});
if (!response.body || !/^text\/event-stream(?:;|$)/i.test(response.headers.get("content-type") ?? "")) {
await response.body?.cancel();
throw new RuntimeApiError("Runtime thread response is not an event stream", { method: "GET", path });
}
if (options.includeProgress && response.headers.get("x-codewhale-event-progress") !== "1") {
await response.body.cancel();
throw new RuntimeCapabilityError("thread_event_progress", "Runtime does not support thread replay progress", { method: "GET", path, status: 501 });
}
yield* parseEventStream(response.body, { maxFrameChars: 2 * 1024 * 1024, requireBoundary: true });
}
async #jsonRequest(path, options = {}) {
const response = await this.#rawRequest(path, options);
if (response.status === 204) {
return null;
}
return response.json();
}
async #rawRequest(path, options = {}) {
const method = options.method ?? "GET";
const headers = new Headers(options.headers);
headers.set("accept", options.accept ?? "application/json");
if (this.token) {
headers.set("authorization", `Bearer ${this.token}`);View on GitHub (pinned to 433685b202)