JuliusBrussee/caveman · error

cave_context_segment_missing

cave_context_segment_missing

Error message

cave_context_segment_missing:${id}

What it means

Thrown during system-prompt assembly when a required context segment id — either 'agent.instructions' or one of the ids listed in definition.contexts — cannot be found in the lowered IR's segments. The runtime builds the prompt from declared context ids and refuses to silently omit one. This is an integrity check between the agent definition and the lowering step.

Solutions

  1. Compare the id in the error with the ids your lowering step emits for lowered.ir.segments and fix the mismatch.
  2. Ensure every definition.contexts entry is actually loaded and lowered (check loader errors/skips upstream).
  3. Log lowered.ir.segments.map(s => s.id) at assembly time to see which ids exist.
  4. Remove or rename the stale context id in the agent definition.

Example fix

// before
definition.contexts = [{ id: "project-docs", ... }]; // lowerer emits "docs"
// after
definition.contexts = [{ id: "docs", ... }]; // matches lowerer output
Defensive patterns

Strategy: validation

Validate before calling

const irIds = new Set(lowered.ir.segments.map(s => s.id));
const missing = ["agent.instructions", ...definition.contexts.map(c => c.id)].filter(id => !irIds.has(id));
if (missing.length) throw new Error(`contexts not lowered: ${missing.join(",")}`);

Type guard

function allSegmentsPresent(ids: string[], segments: { id: string }[]): boolean {
  const have = new Set(segments.map(s => s.id));
  return ids.every(id => have.has(id));
}

Try / catch

try {
  const prompt = assembleSystemPrompt(definition, lowered, bodies);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("cave_context_segment_missing:")) {
    const id = err.message.split(":")[1];
    // fix definition.contexts id or fix lowerer output, then retry
  } else throw err;
}

Prevention

When it happens

Trigger: definition.contexts references a context id that the lowering step never produced as a segment in lowered.ir.segments, or the 'agent.instructions' segment is absent from the IR.

Common situations: A typo or rename mismatch between the context id in the agent definition and the id produced by the context loader/lowerer; a context source that failed to load and was skipped during lowering; stale definition after refactoring context ids.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/fb1d15d59c67fe11. Report an issue: GitHub.

Appendix: source

Thrown at packages/agent/src/runtime.ts:2586

    ["results_artifacts", (bill.artifact ?? 0) + (bill.skill ?? 0) + (bill.tool_result ?? 0)],
    ["output", outputMaxTokens],
  ];
  for (const [slot, used] of slots) {
    if (used > plan.budgets[slot]) throw new Error(`cave_${slot}_budget_exceeded`);
  }
}

export function assembleSystemPrompt(
  definition: AgentDefinition,
  lowered: LoweredContext,
  bodies: ReadonlyMap<string, Uint8Array> = lowered.bodies,
): string {
  const decoder = new TextDecoder();
  const required = ["agent.instructions", ...definition.contexts.map((item) => item.id)];
  const parts: string[] = [];
  for (const id of required) {
    const segment = lowered.ir.segments.find((item) => item.id === id);
    if (!segment) throw new Error(`cave_context_segment_missing:${id}`);
    const body = bodies.get(segment.bodyHandle);
    if (!body) throw new Error(`cave_context_body_missing:${id}`);
    const text = decoder.decode(body);
    parts.push(id === "agent.instructions" ? text : `<cave-context id=${JSON.stringify(id)}>\n${text}\n</cave-context>`);
  }
  if (definition.output) {
    parts.push(`<cave-output max_tokens=${definition.output.maxTokens}>Return output matching declared schema when present.</cave-output>`);
  }
  if (definition.memory) {
    parts.push("<cave-memory>Use cave_memory_search before relying on prior-session facts. Use cave_memory_remember only for durable facts the user intended to retain.</cave-memory>");
  }
  return parts.join("\n\n");
}

async function applyEfficiencyPlan(
  lowered: LoweredContext,
  plan: CavePlan | undefined,
  engineBin: string | undefined,

View on GitHub (pinned to 3ee70a1026)