{"record":{"id":"c61cedb2d61343e3","repo":"Hmbown/CodeWhale","slug":"thread-event-progress","errorCode":"thread_event_progress","errorMessage":"Runtime does not support thread replay progress","messagePattern":"Runtime does not support thread replay progress","errorType":"error_code","errorClass":"RuntimeCapabilityError","httpStatus":501,"severity":"error","filePath":"npm/runtime-sdk/index.js","lineNumber":149,"sourceCode":"      if (value === undefined) continue;\n      if (!Number.isSafeInteger(value) || value < 0) throw new TypeError(`${key} must be a nonnegative safe integer`);\n      query.set(key, String(value));\n    }\n    if (options.includeProgress !== undefined && typeof options.includeProgress !== \"boolean\")\n      throw new TypeError(\"includeProgress must be a boolean\");\n    if (options.includeProgress) query.set(\"progress\", \"true\");\n    const path = `/v1/threads/${segment(threadId)}/events?${query}`;\n    const response = await this.#rawRequest(path, {\n      method: \"GET\", capability: \"thread_event_stream\", accept: \"text/event-stream\",\n      signal: options.signal, redirect: \"error\",\n    });\n    if (!response.body || !/^text\\/event-stream(?:;|$)/i.test(response.headers.get(\"content-type\") ?? \"\")) {\n      await response.body?.cancel();\n      throw new RuntimeApiError(\"Runtime thread response is not an event stream\", { method: \"GET\", path });\n    }\n    if (options.includeProgress && response.headers.get(\"x-codewhale-event-progress\") !== \"1\") {\n      await response.body.cancel();\n      throw new RuntimeCapabilityError(\"thread_event_progress\", \"Runtime does not support thread replay progress\", { method: \"GET\", path, status: 501 });\n    }\n    yield* parseEventStream(response.body, { maxFrameChars: 2 * 1024 * 1024, requireBoundary: true });\n  }\n\n  async #jsonRequest(path, options = {}) {\n    const response = await this.#rawRequest(path, options);\n    if (response.status === 204) {\n      return null;\n    }\n    return response.json();\n  }\n\n  async #rawRequest(path, options = {}) {\n    const method = options.method ?? \"GET\";\n    const headers = new Headers(options.headers);\n    headers.set(\"accept\", options.accept ?? \"application/json\");\n    if (this.token) {\n      headers.set(\"authorization\", `Bearer ${this.token}`);","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/npm/runtime-sdk/index.js#L131-L167","documentation":"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.","triggerScenarios":"client.threadEvents(id, { includeProgress: true }) against a runtime whose /v1/threads/:id/events endpoint omits x-codewhale-event-progress: 1.","commonSituations":"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.","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."],"exampleFix":"// before\nfor await (const ev of client.threadEvents(id, { includeProgress: true })) handle(ev);\n// after\nasync function replay(id, wantProgress) {\n  try {\n    for await (const ev of client.threadEvents(id, { includeProgress: wantProgress })) handle(ev);\n  } catch (err) {\n    if (err?.code === \"thread_event_progress\") return replay(id, false);\n    throw err;\n  }\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"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; } }","preventionTips":["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."],"tags":["capability","version-compatibility","sse","progress"],"backgroundTag":"feature-not-enabled","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}