amruthpillai/reactive-resume · error · Error

Invalid resume URI — expected format: resume://{id}

Error message

Invalid resume URI — expected format: resume://{id}

What it means

MCP resource handler for the 'resume://' resource template strips the resume:// scheme and throws if the remaining id is empty. The resource URI must be resume://{id}; calling resume:// or resume:/// with no id segment is invalid. Generic Error surfaced through the MCP resource read.

Source

Thrown at packages/mcp/src/resources.ts:28

	// Template resource: read resume JSON by ID. Discovery is via list tool (tools), not resources/list.
	const resumeTemplate = new ResourceTemplate("resume://{id}", { list: undefined });

	server.registerResource(
		"resume",
		resumeTemplate,
		{
			title: "Resume Data",
			mimeType: "application/json",
			description: [
				"Full resume data as JSON, including basics, summary, sections, custom sections, and metadata.",
				`Discover resume IDs with the \`${T.listResumes}\` tool, then read \`resume://{id}\` or use \`${T.getResume}\`.`,
				"Appears in `resources/templates/list`; not enumerated in `resources/list`.",
				"Embedded as context in MCP prompts (build_resume, improve_resume, etc.).",
			].join(" "),
		},
		async (uri: URL) => {
			const id = uri.href.replace(/^resume:\/\//, "");
			if (!id) throw new Error("Invalid resume URI — expected format: resume://{id}");

			const resume = await client.resume.getById({ id });

			return {
				contents: [
					{
						uri: uri.href,
						mimeType: "application/json" as const,
						text: JSON.stringify(resume.data, null, 2),
					},
				],
			};
		},
	);

	// ── Resource: resume://_meta/schema ───────────────────────────
	// Static resource containing the JSON Schema for resume data.
	// LLMs should reference this when generating JSON Patch operations

View on GitHub (pinned to 3a5b12e2a4)

Solutions

  1. Always read the resume resource with a concrete id obtained from the listResumes tool: resume://<id>.
  2. Prefer the getResume tool over the resource URI when you already have the id.
  3. Validate the URI matches /^resume:\/\/[\w-]+$/ before issuing resources/read.

Example fix

// before: empty id
await client.resources.read('resume://');
// after: concrete id from listResumes
const { ids } = await client.tools.call('listResumes', {});
await client.resources.read(`resume://${ids[0]}`);
Defensive patterns

Strategy: validation

Validate before calling

const re = /^resume:\/\/[\w-]+$/;
if (!re.test(uri)) throw new TypeError(`Expected resume://{id}, got: ${uri}`);

Type guard

function isResumeUri(uri: string): uri is `resume://${string}` {
  return /^resume:\/\/[\w-]+$/.test(uri);
}

Prevention

When it happens

Trigger: An MCP client reads resources/list and then attempts to read a URI constructed without an id; a client forms resume:// (no id) by mistake; the id was stripped/URL-decoded to empty.

Common situations: Programmatic client that builds URIs from a template variable which was undefined; a malformed URI copy-paste; an automation that iterates an empty id list.

Related errors


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