{"record":{"id":"764221dab1a345d5","repo":"amruthpillai/reactive-resume","slug":"provide-at-least-one-of-name-slug-tags-ispubli","errorCode":null,"errorMessage":"Provide at least one of: name, slug, tags, isPublic.","messagePattern":"Provide at least one of: name, slug, tags, isPublic\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/mcp/src/tools.ts","lineNumber":280,"sourceCode":"\n\t\t\treturn text(`Applied ${operations.length} operation(s) to \"${resume.name}\": ${summary}`);\n\t\t}),\n\t);\n\n\t// ── Update Resume (metadata) ─────────────────��───────────────\n\tserver.registerTool(\n\t\tT.updateResume,\n\t\tTOOL_META[T.updateResume],\n\t\twithErrorHandling(\"updating resume\", async (params) => {\n\t\t\tconst { id, name, slug, tags, isPublic } = params as {\n\t\t\t\tid: string;\n\t\t\t\tname?: string;\n\t\t\t\tslug?: string;\n\t\t\t\ttags?: string[];\n\t\t\t\tisPublic?: boolean;\n\t\t\t};\n\t\t\tif (name === undefined && slug === undefined && tags === undefined && isPublic === undefined)\n\t\t\t\tthrow new Error(\"Provide at least one of: name, slug, tags, isPublic.\");\n\n\t\t\tconst resume = await client.resume.update({\n\t\t\t\tid,\n\t\t\t\t...(name !== undefined ? { name } : {}),\n\t\t\t\t...(slug !== undefined ? { slug } : {}),\n\t\t\t\t...(tags !== undefined ? { tags } : {}),\n\t\t\t\t...(isPublic !== undefined ? { isPublic } : {}),\n\t\t\t});\n\n\t\t\tconst user = await resolveUserFromRequestHeaders(requestHeaders);\n\t\t\tconst username =\n\t\t\t\tuser && \"username\" in user && typeof (user as { username: unknown }).username === \"string\"\n\t\t\t\t\t? (user as { username: string }).username\n\t\t\t\t\t: \"\";\n\t\t\tconst shareUrl =\n\t\t\t\tusername !== \"\"\n\t\t\t\t\t? buildResumeShareUrl(username, resume.slug)\n\t\t\t\t\t: \"(could not build share URL — missing username on account)\";","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/amruthpillai/reactive-resume/blob/3a5b12e2a40374a9571988701fcb75c5a1831c42/packages/mcp/src/tools.ts#L262-L298","documentation":"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).","triggerScenarios":"An MCP client calls updateResume passing only { id }; a caller that conditionally omits every field; a prompt/template that defaults all fields to undefined.","commonSituations":"Automation that builds the params object from optional inputs and ends up with all-undefined; a client that confuses updateResume with a 'refresh' operation.","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."],"exampleFix":"// before\nawait mcp.tools.call('updateResume', { id });\n// after\nawait mcp.tools.call('updateResume', { id, name: 'New name' });","handlingStrategy":"validation","validationCode":"const { id, ...fields } = params;\nif (Object.keys(fields).filter(k => fields[k] !== undefined).length === 0) {\n  throw new TypeError('Pass at least one of: name, slug, tags, isPublic.');\n}","typeGuard":"function hasUpdateField(p: { name?: unknown; slug?: unknown; tags?: unknown; isPublic?: unknown }): boolean {\n  return [p.name, p.slug, p.tags, p.isPublic].some(v => v !== undefined);\n}","tryCatchPattern":null,"preventionTips":["Spread only defined fields and assert at least one is present.","Use getResume if your intent was to read."],"tags":["mcp","validation","resume","precondition"],"backgroundTag":null,"analyzedSha":"3a5b12e2a40374a9571988701fcb75c5a1831c42","analyzedAt":"2026-08-12T22:31:22.666Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}