{"record":{"id":"0af491fc747ab23b","repo":"Hmbown/CodeWhale","slug":"includeprogress-must-be-a-boolean","errorCode":null,"errorMessage":"includeProgress must be a boolean","messagePattern":"includeProgress must be a boolean","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"npm/runtime-sdk/index.js","lineNumber":136,"sourceCode":"        method: \"GET\",\n        path,\n      });\n    }\n    for await (const event of parseEventStream(response.body)) {\n      yield event;\n    }\n  }\n\n  /** Read the existing durable thread journal. This never starts a turn. */\n  async *threadEvents(threadId, options = {}) {\n    const query = new URLSearchParams();\n    for (const [key, value] of [[\"since_seq\", options.sinceSeq], [\"replay_limit\", options.replayLimit]]) {\n      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 = {}) {","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/npm/runtime-sdk/index.js#L118-L154","documentation":"threadEvents() accepts includeProgress to request replay progress markers in the event stream. This TypeError is thrown when includeProgress is provided but is not exactly a boolean. The SDK checks the type strictly because the flag is serialized as a query parameter and also gates a capability check on the response.","triggerScenarios":"Calling threadEvents(id, { includeProgress: 'true' }), { includeProgress: 1 }, or { includeProgress: null } — any defined non-boolean value.","commonSituations":"Boolean flags read from env vars or CLI strings ('true'/'false') passed through unconverted; options objects built generically from JSON where 0/1 was used.","solutions":["Pass a real boolean: Boolean(value) or compare the raw value explicitly (value === 'true').","Coerce env/CLI input before constructing the options object.","Omit includeProgress when you do not need progress markers."],"exampleFix":"// before\nawait client.threadEvents(id, { includeProgress: process.env.SHOW_PROGRESS });\n// after\nawait client.threadEvents(id, { includeProgress: process.env.SHOW_PROGRESS === \"true\" });","handlingStrategy":"validation","validationCode":"const includeProgress = process.env.SHOW_PROGRESS === \"true\";\nif (includeProgress !== undefined && typeof includeProgress !== \"boolean\") throw new TypeError(\"includeProgress must be boolean\");","typeGuard":"const isBool = (v) => v === undefined || typeof v === \"boolean\";","tryCatchPattern":"try { yield* client.threadEvents(id, { includeProgress }); } catch (err) { if (err instanceof TypeError && err.message.includes(\"boolean\")) throw new Error(\"caller bug: includeProgress must be a real boolean\"); throw err; }","preventionTips":["Coerce env/CLI/config strings to booleans at the boundary, not at the call site.","Enable TypeScript strict typing for the options object so non-boolean flags are caught at compile time."],"tags":["typeerror","validation","boolean"],"backgroundTag":"type-mismatch","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"}