JuliusBrussee/caveman · error · Error
cave_execution_authorization_private
Error message
cave_execution_authorization_private
What it means
rejectInternalOptions() guards the public Claude run options: lockedBuild, candidatePlan, and queryFn are internal fields reserved for the framework's own build/execution pipeline (locked builds, candidate evaluation, recorded query injection). A public caller passing any of them is attempting to use private authorization-adjacent machinery, which is refused so callers cannot forge a locked-build execution or smuggle a fake query stream.
Source
Thrown at packages/agent/src/claude-runtime.ts:591
// OAuth subscription runs still expose provider token counts, but catalog
// list price is not money this run paid. Unknown auth also fails closed to
// the honest zero rather than guessing a metered credential.
return { ...usage, priced: false, catalogCostUsd: 0 };
}
function integer(value: unknown): number {
return Number.isSafeInteger(value) && Number(value) >= 0 ? Number(value) : 0;
}
function unprefixClaudeTool(name: string): string {
const prefix = "mcp__caveman_agent__";
return name.startsWith(prefix) ? name.slice(prefix.length) : name;
}
function rejectInternalOptions(options: ClaudeRunOptions): void {
const value = options as Record<string, unknown>;
if ("lockedBuild" in value || "candidatePlan" in value || "queryFn" in value) {
throw new Error("cave_execution_authorization_private");
}
}
function isRecord(value: unknown): value is Record<string, unknown> {
return value !== null && typeof value === "object" && !Array.isArray(value);
}
View on GitHub (pinned to 27d5a3981a)
Solutions
- Remove lockedBuild/candidatePlan/queryFn from the options you pass; construct a fresh public options object with only documented fields.
- If you genuinely need locked/candidate execution, go through the framework's build pipeline (caveman-agent build / dev), not the public run API.
- If a spread is pulling them in, destructure them out: const { lockedBuild, candidatePlan, queryFn, ...public } = internal;
Example fix
// before
await run({ prompt, queryFn: fakeQuery, maxBudgetUsd: 1 });
// after
await run({ prompt, maxBudgetUsd: 1 }); Defensive patterns
Strategy: validation
Validate before calling
const INTERNAL_OPTION_KEYS = ["lockedBuild", "candidatePlan", "queryFn"] as const;
function assertPublicOptions(options: Record<string, unknown>): void {
for (const key of INTERNAL_OPTION_KEYS) {
if (key in options) throw new Error(`option '${key}' is framework-internal`);
}
} Type guard
function isPublicRunOptions(value: unknown): value is ClaudeRunOptions {
if (typeof value !== "object" || value === null) return false;
const keys = Object.keys(value);
return !keys.includes("lockedBuild") && !keys.includes("candidatePlan") && !keys.includes("queryFn");
} Prevention
- Never construct run options by cloning internal framework objects; build them explicitly from documented fields.
- Avoid `as any` on options — it is how internal fields sneak past TypeScript into the runtime guard.
- If a type error pushes you toward lockedBuild/candidatePlan/queryFn, you want the build pipeline, not the public run API.
When it happens
Trigger: Calling the public run API with an options object that includes lockedBuild, candidatePlan, or queryFn — even set to undefined via spread from an internal type, or copied from framework-internal code into application code.
Common situations: Copy-pasting example code from the framework's internal executor into an app; using `as any` to satisfy a type error by passing internal fields; structurally cloning an internal run options object and handing it to the public entry point.
Related errors
- invalid native session identity
- cave_mastra_terminal_failure
- cave_harness_incomplete_evidence
- cave_vercel_usage_missing
- cave_eve_runtime_identity_missing
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/4a0f3bf576b55526.
Report an issue: GitHub.