JuliusBrussee/caveman · error · Error

caveman agent: tool prefix cave_ is reserved by framework ($

Error message

caveman agent: tool prefix cave_ is reserved by framework (${reserved.name})

What it means

Thrown by the agent() builder (packages/agent/src/index.ts:111): a tool in the agent's tools array has a name starting with 'cave_', which is reserved for framework-provided tools. This is the construction-time equivalent of the graph validation check, firing earlier with a clearer message.

Source

Thrown at packages/agent/src/index.ts:111

  contexts?: ContextDefinition[];
  memory?: MemoryDefinition;
  output?: OutputDefinition;
  sandbox?: AgentDefinition["sandbox"];
}): AgentDefinition {
  if (!/^[a-z0-9][a-z0-9_-]{0,95}$/.test(options.id)) {
    throw new Error(`caveman agent: invalid agent id ${JSON.stringify(options.id)}`);
  }
  const tools = Object.freeze([...(options.tools ?? [])]);
  if (new Set(tools.map((item) => item.name)).size !== tools.length) {
    throw new Error("caveman agent: duplicate tool name");
  }
  const sandbox = options.sandbox ?? "required";
  if (!SANDBOX_MODES.includes(sandbox)) {
    throw new Error(`caveman agent: unknown sandbox mode ${JSON.stringify(sandbox)}`);
  }
  const reserved = tools.find((item) => item.name.startsWith("cave_"));
  if (reserved) {
    throw new Error(
      `caveman agent: tool prefix cave_ is reserved by framework (${reserved.name})`,
    );
  }
  const definition: AgentDefinition = {
    kind: "agent",
    id: options.id,
    instructions: options.instructions,
    model: options.model,
    reasoning: options.reasoning ?? "low",
    tools,
    contexts: Object.freeze([...(options.contexts ?? [])]),
    sandbox,
    ...(options.memory === undefined ? {} : { memory: options.memory }),
    ...(options.output === undefined ? {} : { output: options.output }),
  };
  return Object.freeze(definition);
}

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Rename the tool to drop or change the prefix (e.g. 'my_search' instead of 'cave_search').
  2. If wrapping a framework tool, give the wrapper its own non-reserved name.
  3. Add a lint/assert step in shared tool factories rejecting 'cave_'-prefixed names.

Example fix

// before
tool({ name: "cave_retrieve_v2", /* ... */ });

// after
tool({ name: "project_retrieve_v2", /* ... */ });
Defensive patterns

Strategy: validation

Validate before calling

const reserved = tools.find((t) => t.name.startsWith("cave_"));
if (reserved) throw new Error(`rename '${reserved.name}': cave_ prefix is framework-reserved`);

Type guard

function hasReservedPrefix(name: string): boolean {
  return name.startsWith("cave_");
}

Prevention

When it happens

Trigger: Calling agent({ tools: [tool({ name: 'cave_...', ... })] }) — any tool whose name begins with the reserved prefix 'cave_'.

Common situations: Naming a wrapper around a framework tool with the same 'cave_' prefix; teams adopting a 'cave_' naming convention for their project; wrapping framework tools and forwarding the original name.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/918f50e5c43a14f6. Report an issue: GitHub.