thedotmack/claude-mem · error
file_path is required
Error message
file_path is required
What it means
resolveWithinWorkspace resolves a requested file path safely within the workspace root for MCP smart-file-read tools. It throws 'file_path is required' when the filePath argument is missing, not a string, or empty/whitespace-only.
Solutions
- Supply a non-empty file_path string in the MCP tool call, e.g. file_path: "src/index.ts".
- Fix the client code so the parameter is actually populated (check for failed interpolation or undefined variables).
- Validate the argument client-side before invoking: typeof p === 'string' && p.trim().length > 0.
Example fix
// before
await read({ file_path: opts.path ?? '' });
// after
if (!opts.path || !opts.path.trim()) throw new Error('file_path is required');
await read({ file_path: opts.path }); Defensive patterns
Strategy: validation
Validate before calling
function hasFilePath(args: unknown): args is { file_path: string } {
return typeof args === 'object' && args !== null &&
typeof (args as any).file_path === 'string' && (args as any).file_path.trim().length > 0;
} Type guard
function isNonEmptyString(v: unknown): v is string {
return typeof v === 'string' && v.trim().length > 0;
} Try / catch
try {
const resolved = await resolveWithinWorkspace(args.file_path);
} catch (err) {
if (String(err) === 'Error: file_path is required') return mcpError(400, 'file_path parameter is required');
throw err;
} Prevention
- Enforce file_path as required in the MCP tool's JSON schema.
- Check for empty template variables before dispatching tool calls.
- Trim and validate user input at the client boundary.
When it happens
Trigger: An MCP file tool call passes file_path as empty string, whitespace, null/undefined, or a non-string value (e.g. a number or object) into resolveWithinWorkspace.
Common situations: Client omits the file_path parameter in the tool call; a template variable failed to interpolate and left an empty string; JSON schema on the client side does not enforce the parameter.
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
- " " is required
- observation_add: "content" is required
- Missing required argument: name
- 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/75af9ec2deaf86f3.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/smart-file-read/workspace-path.ts:30
/**
* Resolve a caller-supplied path and refuse anything that escapes the workspace.
*
* smart_unfold / smart_outline / smart_search used to `resolve()` the argument
* with no containment check, so an MCP call could read ~/.ssh/id_rsa (and any
* other file the OS user can read). path.resolve() is lexical only — it does
* not follow symlinks — so both sides are realpath'd before the comparison.
* Missing targets fall back to the lexical path so the caller still gets a
* natural ENOENT, but only after the lexical path itself is known not to escape.
*
* @see thedotmack/claude-mem#3861
*/
export async function resolveWithinWorkspace(
filePath: string,
workspaceCwd: string = process.cwd(),
): Promise<string> {
if (typeof filePath !== 'string' || filePath.trim().length === 0) {
throw new Error('file_path is required');
}
const root = await realpath(resolve(workspaceCwd));
const lexicallyResolved = resolve(root, expandLeadingTilde(filePath.trim()));
let resolved: string;
try {
resolved = await realpath(lexicallyResolved);
} catch {
resolved = lexicallyResolved;
}
if (resolved !== root && !resolved.startsWith(root + sep)) {
throw new Error(
`Access denied: "${filePath}" resolves outside the workspace (${root}). ` +
'MCP file tools can only read files within the current project.',
);
}
View on GitHub (pinned to d8bc9755e7)