JuliusBrussee/caveman · warning
${key} is required
Error message
${key} is required What it means
stringArg() in the CLI's MCP tool layer (packages/cli/src/agent-mcp.ts) throws when a required string argument is absent, not a string, or whitespace-only. It backs tools like caveman_report (report), caveman_trace_get (trace_id), and caveman_experiment_get (action, experiment_id), so the MCP client sees an isError result naming the missing key.
Source
Thrown at packages/cli/src/agent-mcp.ts:410
function metadataOnlyTrace(trace: JSONValue): JSONObject {
return allowlistedObject(trace, AGENT_TRACE_FIELDS);
}
function metadataOnlySpans(value: JSONValue): JSONObject {
if (!value || typeof value !== "object" || Array.isArray(value)) return { spans: [], timeline: [] };
const spans = Array.isArray(value.spans)
? value.spans.map((span) => allowlistedObject(span, AGENT_SPAN_FIELDS))
: [];
const timeline = Array.isArray(value.timeline)
? value.timeline.map((event) => allowlistedObject(event, AGENT_TIMELINE_FIELDS))
: [];
return { spans, timeline };
}
function stringArg(args: JSONObject, key: string): string {
const value = args[key];
if (typeof value !== "string" || value.trim() === "") throw new Error(`${key} is required`);
return value;
}
function result(value: JSONValue): ToolResult {
const structuredContent = value && typeof value === "object" && !Array.isArray(value)
? value as JSONObject
: { value };
return {
content: [{ type: "text", text: JSON.stringify(structuredContent) }],
structuredContent,
};
}
function errorResult(error: unknown): ToolResult {
const candidate = error as { message?: unknown; code?: unknown; status?: unknown };
const structuredContent: JSONObject = {
error: typeof candidate.code === "string" ? candidate.code : "cave_agent_tool_failed",
message: typeof candidate.message === "string" ? candidate.message : "Caveman tool failed.",View on GitHub (pinned to 27d5a3981a)
Solutions
- Supply the named argument as a non-empty string (e.g. {"trace_id": "abc123"}).
- Stringify numeric ids before calling: String(experimentId).
- Define the argument as required in your MCP client's tool schema so the model cannot omit it.
Example fix
// before
callTool("caveman_trace_get", {})
// after
callTool("caveman_trace_get", { trace_id: "01J8Z..." }) Defensive patterns
Strategy: validation
Validate before calling
function requireStringArg(args: Record<string, unknown>, key: string): string {
const v = args[key];
if (typeof v !== "string" || v.trim() === "") throw new Error(`${key} is required`);
return v;
}
// before calling caveman_trace_get / caveman_report / caveman_experiment_get:
requireStringArg(args, "trace_id"); Type guard
function isNonEmptyString(v: unknown): v is string {
return typeof v === "string" && v.trim() !== "";
} Try / catch
try { await client.callTool("caveman_trace_get", args); } catch (e) { if (e instanceof Error && /is required$/.test(e.message)) { /* prompt for the missing arg, do not retry unchanged */ } throw e; } Prevention
- Declare required string args in your MCP client schema.
- Stringify ids at the boundary; never pass numbers where ids are expected.
- Check the error message for the exact key name it names.
When it happens
Trigger: Calling caveman_trace_get without trace_id; passing trace_id as a number; sending "" or " " for report/action/experiment_id; an LLM omitting the argument in its tool-call JSON.
Common situations: A model-generated tool call drops a required field; a client sends numeric ids (e.g. 12345 instead of "12345"); copy-paste payloads trimmed to placeholders.
Related errors
- --provider requires a value
- unknown option ${value}
- unknown command ${JSON.stringify(command)}; run caveman-agen
- cave_subagent_arguments_invalid
- filters must be an object
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/cd230833f43c8cf6.
Report an issue: GitHub.