amruthpillai/reactive-resume · error · Error

Application documents must be PDF files.

Error message

Application documents must be PDF files.

What it means

fileFromBase64 enforces that application documents submitted through an MCP tool are PDFs: it throws if input.contentType !== 'application/pdf'. This is a hard format gate for cover-letter / application-document upload tooling before constructing the File used downstream.

Source

Thrown at packages/mcp/src/tools.ts:64

		} catch (error) {
			return {
				isError: true,
				content: [{ type: "text", text: `Error ${label}: ${errorMessage(error)}${errorHint(error)}` }],
			};
		}
	};
}

function text(value: string): CallToolResult {
	return { content: [{ type: "text", text: value }] };
}

function json(value: unknown): CallToolResult {
	return text(JSON.stringify(value, null, 2));
}

function fileFromBase64(input: { fileName: string; contentType: string; dataBase64: string }): File {
	if (input.contentType !== "application/pdf") throw new Error("Application documents must be PDF files.");

	const bytes = Buffer.from(input.dataBase64, "base64");
	if (bytes.length === 0) throw new Error("Application document cannot be empty.");

	return new File([bytes], input.fileName, { type: input.contentType });
}

function coerceFollowUpAt(input: Record<string, unknown>): Record<string, unknown> {
	if (!("followUpAt" in input)) return input;

	const followUpAt = input.followUpAt;
	if (followUpAt === undefined || followUpAt === null || followUpAt instanceof Date) return input;

	return { ...input, followUpAt: new Date(String(followUpAt)) };
}

function buildResumeShareUrl(username: string, slug: string): string {
	const base = env.APP_URL.replace(/\/$/, "");

View on GitHub (pinned to 3a5b12e2a4)

Solutions

  1. Convert the source document to PDF before submission and set contentType: 'application/pdf'.
  2. If you only have bytes, sniff the magic bytes (%PDF-) and set contentType accordingly, or reject early client-side.
  3. Ensure the fileName also ends in .pdf to avoid downstream content-type inference mismatches.

Example fix

// before
{ fileName: 'cover.docx', contentType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', dataBase64 }
// after (convert to PDF first)
{ fileName: 'cover.pdf', contentType: 'application/pdf', dataBase64: pdfBase64 }
Defensive patterns

Strategy: validation

Validate before calling

if (input.contentType !== 'application/pdf') {
  throw new TypeError('Application documents must be PDF; convert the file first.');
}

Type guard

function isPdfInput(i: { contentType: string }): boolean {
  return i.contentType === 'application/pdf';
}

Prevention

When it happens

Trigger: An MCP tool call submits a document with contentType 'application/msword', 'image/png', 'text/plain', or an empty/wrong MIME; the caller guessed the content type instead of reading it from the file.

Common situations: Automation that re-uses a generic MIME for any document; a client that doesn't detect the file type; a DOC converted to PDF but mislabeled.

Related errors


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