thedotmack/claude-mem · error
" " is required
Error message
"${key}" is required What it means
requireString() in the recall MCP server validates tool-call arguments. If a required argument is absent, not a string, or an empty/whitespace-only string, it throws `"<key>" is required`. This gives tool callers a clear, per-key message instead of undefined behavior downstream.
Solutions
- Include the required key in the tool-call arguments as a non-empty string (e.g. projectId: 'my-project')
- Coerce client-side values to strings before invoking (String(projectId))
- If 'all projects' is intended, use a tool designed for it rather than an empty projectId
Example fix
// before
await client.callTool('observations', { projectId: 42 });
// after
await client.callTool('observations', { projectId: String(42) }); Defensive patterns
Strategy: validation
Validate before calling
function assertArgs(args: Record<string, unknown>): void {
if (typeof args.projectId !== 'string' || args.projectId.trim().length === 0) {
throw new Error('"projectId" is required');
}
} Type guard
const hasProjectId = (a: Record<string, unknown>): a is Record<string, unknown> & { projectId: string } =>
typeof a.projectId === 'string' && a.projectId.trim().length > 0; Try / catch
try {
const result = await callRecallTool('observations', args);
} catch (e) {
if (e instanceof Error && e.message === '"projectId" is required') {
// prompt user for a projectId or return a clear client-side error
}
throw e;
} Prevention
- Validate tool arguments against the tool's input schema before calling
- Always send string-typed IDs (UUIDs as strings, never numbers)
- Reject empty/whitespace strings client-side before dispatch
When it happens
Trigger: Calling a tool (e.g. the observations tool) without the 'projectId' argument, passing it as a non-string (number, object), or passing an empty/blank string.
Common situations: MCP client omitting arguments from the tool-call input object; sending numbers/UUIDs as non-string JSON types; test harnesses with partially filled argument maps; a client using a null projectId for 'all projects'.
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
- file_path is required
- Missing required argument: name
- observation_add: "content" is required
- observation_context: "query" is required
- observation_generation_status: "jobId" is required
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/4c51c53b66ffded8.
Report an issue: GitHub.
Appendix: source
Thrown at src/server/mcp/recall-mcp-server.ts:90
type: 'object',
properties: {
projectId: { type: 'string', description: 'Project to list.' },
limit: { type: 'integer', minimum: 1, maximum: RECENT_LIMIT.max },
},
required: ['projectId'],
},
},
];
function clampLimit(raw: unknown, spec: { default: number; max: number }): number {
if (typeof raw !== 'number' || !Number.isFinite(raw)) return spec.default;
return Math.min(Math.max(1, Math.trunc(raw)), spec.max);
}
function requireString(args: Record<string, unknown>, key: string): string {
const value = args[key];
if (typeof value !== 'string' || value.trim().length === 0) {
throw new Error(`"${key}" is required`);
}
return value;
}
function jsonResult(payload: unknown): CallToolResult {
return { content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }] };
}
// Dispatches a single tool call to the backend. Throws on unknown tools or
// invalid arguments; `createRecallMcpServer` converts those into MCP errors.
async function dispatchToolCall(
backend: RecallBackend,
name: string,
args: Record<string, unknown>,
): Promise<CallToolResult> {
if (name === 'search') {
const observations = await backend.search({
projectId: requireString(args, 'projectId'),View on GitHub (pinned to d8bc9755e7)