JuliusBrussee/caveman · error
is required
Error message
${key} is required What it means
stringArg is the agent-MCP tool layer's argument validator: it asserts that args[key] exists, is a string, and is non-empty after trimming. Handlers for commands like report, trace, and actions call it to extract mandatory identifiers. It throws `${key} is required` when the argument is missing, of the wrong type, or whitespace-only.
Solutions
- Add the required argument as a non-empty string to the tool call arguments
- Coerce numeric/other ids to string before invoking (String(id))
- Check the tool's input schema for the exact required key names (report's id, trace's traceId, etc.)
- Trim user-supplied input to ensure it isn't blank
Example fix
// before
callTool('report', { format: 'json' }); // missing id
callTool('report', { id: 42 });
// after
callTool('report', { format: 'json', id: '42' }); Defensive patterns
Strategy: validation
Validate before calling
function requireString(args, key) {
const v = args[key];
if (typeof v !== 'string' || v.trim() === '') throw new Error(`${key} is required`);
return v;
}
// call before invoking the tool: requireString(args, 'traceId') Type guard
function isNonEmptyString(v) {
return typeof v === 'string' && v.trim().length > 0;
} Try / catch
try {
await callTool('trace', { traceId });
} catch (error) {
if (error.message.endsWith('is required')) {
// prompt user/model for the missing argument and retry
}
} Prevention
- Read each tool's input schema and always supply required keys
- Coerce ids to strings before sending (String(id))
- Validate tool-call arguments with a schema validator (zod/ajv) before dispatching
- Trim inputs; reject blank strings at the source (UI or client)
When it happens
Trigger: Calling the MCP tools report, trace (traceId), or an action requiring action/experimentId without that key in args, with a non-string value (number/null/object), or with an empty/whitespace string.
Common situations: MCP client omitting a required tool argument; passing a numeric id as a JSON number instead of a string; passing null; an LLM generating tool calls that drop required params; whitespace-only values from copy/paste.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- must be one of
- at least one report path and the canonical span fixture…
- cave_budget_release_reason_required
- cave_subagent_arguments_invalid
- cave_tool_input_schema_mismatch
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/cd230833f43c8cf6.
Report an issue: GitHub.
Appendix: 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 3ee70a1026)