amruthpillai/reactive-resume · warning · Error
Provide at least one of: name, slug, tags, isPublic.
Error message
Provide at least one of: name, slug, tags, isPublic.
What it means
updateResume MCP tool requires at least one mutable field. If name, slug, tags, and isPublic are all undefined it throws immediately, before calling the API. This is a manual precondition guard (the underlying API may accept a no-op, but the tool refuses it to give a clear error).
Source
Thrown at packages/mcp/src/tools.ts:280
return text(`Applied ${operations.length} operation(s) to "${resume.name}": ${summary}`);
}),
);
// ── Update Resume (metadata) ─────────────────��───────────────
server.registerTool(
T.updateResume,
TOOL_META[T.updateResume],
withErrorHandling("updating resume", async (params) => {
const { id, name, slug, tags, isPublic } = params as {
id: string;
name?: string;
slug?: string;
tags?: string[];
isPublic?: boolean;
};
if (name === undefined && slug === undefined && tags === undefined && isPublic === undefined)
throw new Error("Provide at least one of: name, slug, tags, isPublic.");
const resume = await client.resume.update({
id,
...(name !== undefined ? { name } : {}),
...(slug !== undefined ? { slug } : {}),
...(tags !== undefined ? { tags } : {}),
...(isPublic !== undefined ? { isPublic } : {}),
});
const user = await resolveUserFromRequestHeaders(requestHeaders);
const username =
user && "username" in user && typeof (user as { username: unknown }).username === "string"
? (user as { username: string }).username
: "";
const shareUrl =
username !== ""
? buildResumeShareUrl(username, resume.slug)
: "(could not build share URL — missing username on account)";View on GitHub (pinned to 3a5b12e2a4)
Solutions
- Pass at least one of name, slug, tags, or isPublic with a defined value.
- Build the params object by spreading only defined fields and assert Object.keys(params).length > 1 (besides id) before calling.
- If your intent was to read the resume, use getResume instead.
Example fix
// before
await mcp.tools.call('updateResume', { id });
// after
await mcp.tools.call('updateResume', { id, name: 'New name' }); Defensive patterns
Strategy: validation
Validate before calling
const { id, ...fields } = params;
if (Object.keys(fields).filter(k => fields[k] !== undefined).length === 0) {
throw new TypeError('Pass at least one of: name, slug, tags, isPublic.');
} Type guard
function hasUpdateField(p: { name?: unknown; slug?: unknown; tags?: unknown; isPublic?: unknown }): boolean {
return [p.name, p.slug, p.tags, p.isPublic].some(v => v !== undefined);
} Prevention
- Spread only defined fields and assert at least one is present.
- Use getResume if your intent was to read.
When it happens
Trigger: An MCP client calls updateResume passing only { id }; a caller that conditionally omits every field; a prompt/template that defaults all fields to undefined.
Common situations: Automation that builds the params object from optional inputs and ends up with all-undefined; a client that confuses updateResume with a 'refresh' operation.
Related errors
- BAD_REQUEST
- BAD_REQUEST
- INVALID_PATCH_OPERATIONS
- STYLESHEET_PARITY_FAILED
- JSON.stringify(flattenError(error))
AI-assisted analysis of amruthpillai/reactive-resume@3a5b12e2a4 (2026-08-12).
Data as JSON: /api/errors/764221dab1a345d5.
Report an issue: GitHub.