JuliusBrussee/caveman · error · Error
cave_context_ir_invalid
cave_context_ir_invalid
Error message
cave_context_ir_invalid
What it means
contextIRFromWire is the deserialization boundary for the Context IR format. The 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 other shape — including forward-compatible future versions — is rejected as cave_context_ir_invalid.
Source
Thrown at packages/agent/src/context-ir.ts:85
stability: segment.stability,
safety: segment.safety,
priority: segment.priority,
recovery: segment.recovery,
cache_region: segment.cacheRegion,
privacy: segment.privacy,
opaque: segment.opaque,
...(segment.ttlTurns === undefined ? {} : { ttl_turns: segment.ttlTurns }),
provenance_digest: segment.provenanceDigest,
token_count: segment.tokenCount,
body_handle: segment.bodyHandle,
})),
};
}
export function contextIRFromWire(value: unknown): ContextIR {
if (!isRecord(value) || !exactKeys(value, ["schema_version", "segments"]) ||
value.schema_version !== 1 || !Array.isArray(value.segments)) {
throw new Error("cave_context_ir_invalid");
}
const segments = value.segments.map((item): ContextSegment => {
const required = [
"id", "kind", "stability", "safety", "priority", "recovery", "cache_region",
"privacy", "opaque", "provenance_digest", "token_count", "body_handle",
];
if (!isRecord(item) ||
!(exactKeys(item, required) || exactKeys(item, [...required, "ttl_turns"])) ||
typeof item.id !== "string" || item.id.length === 0 ||
!known(item.kind, ["instruction", "user_intent", "tool_schema", "skill", "memory", "history", "tool_result", "artifact", "error", "output_contract"]) ||
!known(item.stability, ["build", "session", "turn"]) ||
!known(item.safety, ["S0", "S1", "S2", "S3", "S4"]) ||
!known(item.priority, ["required", "high", "normal", "low"]) ||
!known(item.recovery, ["none", "exact_ccr", "source_ref", "recompute"]) ||
!known(item.cache_region, ["frozen_prefix", "live_zone", "uncached"]) ||
!known(item.privacy, ["content_blind", "local_sensitive", "connected_allowed"]) ||
typeof item.opaque !== "boolean" ||
!/^[0-9a-f]{64}$/.test(String(item.provenance_digest)) ||View on GitHub (pinned to 27d5a3981a)
Solutions
- Regenerate the wire payload with contextIRToWire from the same package version and retry
- Pin all services that exchange Context IR to the same package version so schema_version matches
- Parse the JSON once before passing (typeof value === 'string' ? JSON.parse(value) : value)
- Add a version dispatch layer: read schema_version first and migrate older shapes before calling contextIRFromWire
Example fix
// before const ir = contextIRFromWire(raw); // raw had schema_version: 2 or extra keys // after: re-serialize with the current codec const wire = contextIRToWire(ir); const roundTripped = contextIRFromWire(JSON.parse(JSON.stringify(wire)));
Defensive patterns
Strategy: type-guard
Validate before calling
function looksLikeContextIREnvelope(v: unknown): boolean {
return typeof v === "object" && v !== null &&
Object.keys(v).length === 2 &&
(v as any).schema_version === 1 &&
Array.isArray((v as any).segments);
} Type guard
function isContextIRWire(v: unknown): v is { schema_version: 1; segments: unknown[] } {
return isRecord(v) &&
exactKeysCheck(v, ["schema_version", "segments"]) &&
v.schema_version === 1 && Array.isArray(v.segments);
} Try / catch
try {
const ir = contextIRFromWire(payload);
} catch (err) {
if (err instanceof Error && err.message === "cave_context_ir_invalid") {
// treat as a version/shape mismatch: regenerate payload with contextIRToWire
throw new Error(`Context IR payload rejected; regenerate with the current codec (schema_version=${(payload as any)?.schema_version})`);
}
throw err;
} Prevention
- Round-trip payloads through contextIRToWire/contextIRFromWire from the same package version
- Pin package versions across all services exchanging Context IR
- Parse JSON exactly once before deserialization
When it happens
Trigger: Feeding contextIRFromWire JSON that: is not an object; carries extra top-level keys; has schema_version 2 or '1' (string); has segments as an object rather than array; or was double-encoded (a JSON string of JSON).
Common situations: Persisted IR from a newer/older package version with a different schema_version; hand-crafted fixtures in tests; payloads relayed through queues that JSON.stringify twice; renamed top-level fields during refactors.
Related errors
- cave_harness_wire_contract_invalid
- caveman agent: value is not canonically serializable
- option not found
- cave_harness_adapter_version_invalid
- cave_harness_model_invalid
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/1708b9b7400b108b.
Report an issue: GitHub.