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

  1. Pass at least one of name, slug, tags, or isPublic with a defined value.
  2. Build the params object by spreading only defined fields and assert Object.keys(params).length > 1 (besides id) before calling.
  3. 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

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


AI-assisted analysis of amruthpillai/reactive-resume@3a5b12e2a4 (2026-08-12). Data as JSON: /api/errors/764221dab1a345d5. Report an issue: GitHub.