{"record":{"id":"27dc6e7aab56c935","repo":"Hmbown/CodeWhale","slug":"invalid-runtime-envelope","errorCode":null,"errorMessage":"Invalid Runtime envelope.","messagePattern":"Invalid Runtime envelope\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"pet/scripts/lib/pet-runtime.mjs","lineNumber":59,"sourceCode":"        if (response.headers.get('x-codewhale-event-progress') !== '1') {\n          await response.body.cancel();\n          const error = new Error('Runtime replay progress is unavailable.'); error.status = 501; throw error;\n        }\n        // Cancel the wrapped pipeline too: the original Response can be collected\n        // while its idle body is still being read through the replacement below.\n        const body = response.body.pipeThrough(new TransformStream({ transform(chunk, controller) { refresh(); controller.enqueue(chunk); } }), { signal });\n        return new Response(body, { status: response.status, headers: response.headers });\n      };\n      try {\n        for await (const record of client.threadEvents(threadId, { sinceSeq: cursor, signal, includeProgress: true })) {\n          if (record?.event === 'stream.progress') {\n            if (record.thread_id !== threadId || record.seq !== cursor || !['live', 'replaying'].includes(record.state))\n              throw new Error('Invalid Runtime replay progress.');\n            connected = record.state === 'live';\n            continue;\n          }\n          if (!isCodewhaleRuntimeRecord(record) || record.thread_id !== threadId || !Number.isSafeInteger(record.seq) || record.seq < 0)\n            throw new Error('Invalid Runtime envelope.');\n          if (record.seq <= cursor) continue;\n          // Sequence numbers belong to Runtime, and need not be consecutive.\n          // Its predecessor cursor detects loss without inventing a new counter.\n          if (record.previous_seq !== undefined && record.previous_seq !== cursor)\n            throw new Error('Runtime predecessor cursor does not match.');\n          if (record.event !== 'item.delta') {\n            // The existing importer retains unfinished lifetimes and a recent\n            // recurrence window, not a second copy of the entire raw journal.\n            if (revision % 256 === 0) trace.prune(Date.now() - 16_000);\n            try { trace.append([redact(record)]); }\n            catch (error) { fatal = true; throw error; }\n            revision++;\n          }\n          cursor = record.seq; backoff = 250;\n        }\n      } catch (error) {\n        if ([400, 401, 403, 404, 405, 501].includes(error.status)) fatal = true;\n        if (!shutdown.signal.aborted) report(fatal","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/pet/scripts/lib/pet-runtime.mjs#L41-L77","documentation":"Every non-progress record from client.threadEvents() must pass isCodewhaleRuntimeRecord(), carry the matching thread_id, and have a non-negative safe-integer seq. This is the envelope integrity gate: a malformed, foreign-thread, or incorrectly-sequenced record means the journal stream is corrupt or the server is speaking a different protocol version.","triggerScenarios":"client.threadEvents() yields a record that fails isCodewhaleRuntimeRecord (missing/extra fields, wrong shape), has record.thread_id !== threadId, or record.seq is not a Number.isSafeInteger >= 0 (undefined, negative, float, > 2^53-1).","commonSituations":"Connecting to a Runtime server of a different protocol version; a transparent proxy mangling JSON payloads; reading a journal file written by another tool; requesting a thread ID whose records contain a different (canonical) thread_id than the one passed on the CLI.","solutions":["Print the failing record to see whether it fails the shape check, thread_id match, or seq check.","Verify the --thread ID exactly matches the thread_id embedded in the journal records (case/ID canonicalization).","Align Runtime server and client versions so the record schema matches isCodewhaleRuntimeRecord's expectation.","Check for intermediaries (proxies, log tailers) that could rewrite or truncate records; connect directly to the Runtime endpoint."],"exampleFix":"// before: opaque throw\nif (!isCodewhaleRuntimeRecord(record) || record.thread_id !== threadId || !Number.isSafeInteger(record.seq) || record.seq < 0)\n  throw new Error('Invalid Runtime envelope.');\n// after: localized diagnosis\nif (!isCodewhaleRuntimeRecord(record) || record.thread_id !== threadId || !Number.isSafeInteger(record.seq) || record.seq < 0) {\n  console.error('envelope', JSON.stringify(record)?.slice(0, 500), 'want thread', threadId);\n  throw new Error('Invalid Runtime envelope.');\n}","handlingStrategy":"validation","validationCode":"function validEnvelope(record, threadId) {\n  return isCodewhaleRuntimeRecord(record) &&\n    record.thread_id === threadId &&\n    Number.isSafeInteger(record.seq) && record.seq >= 0;\n}\n// skip records failing validEnvelope after logging them","typeGuard":"const isCodewhaleRuntimeRecord = (r) =>\n  r != null && typeof r === 'object' && typeof r.thread_id === 'string' &&\n  typeof r.event === 'string' && Number.isSafeInteger(r.seq);","tryCatchPattern":"try {\n  await followRuntime({ baseUrl, threadId });\n} catch (err) {\n  if (err.message === 'Invalid Runtime envelope.') {\n    console.error('Check server/client protocol versions and thread ID canonicalization');\n  }\n  throw err;\n}","preventionTips":["Use the exact thread ID the server reports (no case or prefix changes).","Connect directly to the Runtime endpoint; avoid rewriting proxies.","Confirm record schema against isCodewhaleRuntimeRecord after any server upgrade."],"tags":["streaming","schema-validation","runtime","protocol"],"backgroundTag":"schema-validation-failed","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"}