{"record":{"id":"1708b9b7400b108b","repo":"JuliusBrussee/caveman","slug":"cave-context-ir-invalid","errorCode":"cave_context_ir_invalid","errorMessage":"cave_context_ir_invalid","messagePattern":"cave_context_ir_invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/context-ir.ts","lineNumber":85,"sourceCode":"      stability: segment.stability,\n      safety: segment.safety,\n      priority: segment.priority,\n      recovery: segment.recovery,\n      cache_region: segment.cacheRegion,\n      privacy: segment.privacy,\n      opaque: segment.opaque,\n      ...(segment.ttlTurns === undefined ? {} : { ttl_turns: segment.ttlTurns }),\n      provenance_digest: segment.provenanceDigest,\n      token_count: segment.tokenCount,\n      body_handle: segment.bodyHandle,\n    })),\n  };\n}\n\nexport function contextIRFromWire(value: unknown): ContextIR {\n  if (!isRecord(value) || !exactKeys(value, [\"schema_version\", \"segments\"]) ||\n      value.schema_version !== 1 || !Array.isArray(value.segments)) {\n    throw new Error(\"cave_context_ir_invalid\");\n  }\n  const segments = value.segments.map((item): ContextSegment => {\n    const required = [\n      \"id\", \"kind\", \"stability\", \"safety\", \"priority\", \"recovery\", \"cache_region\",\n      \"privacy\", \"opaque\", \"provenance_digest\", \"token_count\", \"body_handle\",\n    ];\n    if (!isRecord(item) ||\n        !(exactKeys(item, required) || exactKeys(item, [...required, \"ttl_turns\"])) ||\n        typeof item.id !== \"string\" || item.id.length === 0 ||\n        !known(item.kind, [\"instruction\", \"user_intent\", \"tool_schema\", \"skill\", \"memory\", \"history\", \"tool_result\", \"artifact\", \"error\", \"output_contract\"]) ||\n        !known(item.stability, [\"build\", \"session\", \"turn\"]) ||\n        !known(item.safety, [\"S0\", \"S1\", \"S2\", \"S3\", \"S4\"]) ||\n        !known(item.priority, [\"required\", \"high\", \"normal\", \"low\"]) ||\n        !known(item.recovery, [\"none\", \"exact_ccr\", \"source_ref\", \"recompute\"]) ||\n        !known(item.cache_region, [\"frozen_prefix\", \"live_zone\", \"uncached\"]) ||\n        !known(item.privacy, [\"content_blind\", \"local_sensitive\", \"connected_allowed\"]) ||\n        typeof item.opaque !== \"boolean\" ||\n        !/^[0-9a-f]{64}$/.test(String(item.provenance_digest)) ||","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/context-ir.ts#L67-L103","documentation":"contextIRFromWire validates an untrusted wire value before reconstructing a ContextIR. The top-level envelope must be a record with exactly the keys schema_version and segments, schema_version must be 1, and segments must be an array; any deviation throws cave_context_ir_invalid.","triggerScenarios":"Feeding a wire payload missing schema_version or segments; payloads with extra/renamed keys; schema_version other than 1; segments not an array (null, object, string) — typically from corrupt caches or tampered network data.","commonSituations":"Truncated JSON cache files that parse as valid JSON but wrong shape; API responses from a service writing a different schema; hand-edited fixture files in tests.","solutions":["Ensure the payload has exactly schema_version: 1 and an array segments field with no extra keys","Regenerate the wire payload with contextIRToWire from a valid ContextIR","Wrap the call in try/catch and fall back to rebuilding the IR from origin data"],"exampleFix":"// before\nconst ir = contextIRFromWire({ segments: [] });\n// after\nconst ir = contextIRFromWire({ schema_version: 1, segments: [] });","handlingStrategy":"type-guard","validationCode":"function looksLikeWire(v: unknown): boolean {\n  return typeof v === \"object\" && v !== null &&\n    Object.keys(v).sort().join() === \"schema_version,segments\" &&\n    (v as any).schema_version === 1 && Array.isArray((v as any).segments);\n}\nif (!looksLikeWire(payload)) throw new Error(\"payload is not a v1 ContextIR wire object\");","typeGuard":"const isIRWire = (v: unknown): v is ContextIRWire =>\n  typeof v === \"object\" && v !== null &&\n  Object.keys(v).length === 2 &&\n  (v as any).schema_version === 1 && Array.isArray((v as any).segments);","tryCatchPattern":"try {\n  const ir = contextIRFromWire(payload);\n} catch (err) {\n  if ((err as Error).message === \"cave_context_ir_invalid\") {\n    console.error(\"Discarding malformed ContextIR payload; rebuilding from origin\");\n    ir = rebuildFromOrigin();\n  } else throw err;\n}","preventionTips":["Produce wire payloads only via contextIRToWire; never hand-build them","Validate untrusted payloads (caches, network) with a type guard before deserialization","Keep exactly schema_version and segments at top level — no extra keys"],"tags":["schema","validation","deserialization"],"backgroundTag":"schema-validation-failed","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}