modelcontextprotocol/servers · error · Error
Invalid resourceType: ${args?.resourceType}. Must be ${RESOU
Error message
Invalid resourceType: ${args?.resourceType}. Must be ${RESOURCE_TYPE_TEXT} or ${RESOURCE_TYPE_BLOB}. What it means
Thrown by the `get-resource-reference` tool when `resourceType` is not in RESOURCE_TYPES. Unlike the prompt variant, this tool's zod schema (`z.enum(["Text","Blob"]).default("Text")`) already constrains the value, so reaching this throw means the schema default was bypassed or args were passed unvalidated.
Source
Thrown at src/everything/tools/get-resource-reference.ts:60
* The registered tool validates and processes arguments for retrieving a resource
* reference. Supported resource types include predefined `RESOURCE_TYPE_TEXT` and
* `RESOURCE_TYPE_BLOB`. The retrieved resource's reference will include the resource
* ID, type, and its associated URI.
*
* The tool performs the following operations:
* 1. Validates the `resourceType` argument to ensure it matches a supported type.
* 2. Validates the `resourceId` argument to ensure it is a finite positive integer.
* 3. Constructs a URI for the resource based on its type (text or blob).
* 4. Retrieves the resource and returns it in a content block.
*
* @param {McpServer} server - The McpServer instance where the tool will be registered.
*/
export const registerGetResourceReferenceTool = (server: McpServer) => {
server.registerTool(name, config, async (args): Promise<CallToolResult> => {
// Validate resource type argument
const { resourceType } = args;
if (!RESOURCE_TYPES.includes(resourceType)) {
throw new Error(
`Invalid resourceType: ${args?.resourceType}. Must be ${RESOURCE_TYPE_TEXT} or ${RESOURCE_TYPE_BLOB}.`
);
}
// Validate resourceId argument
const resourceId = Number(args?.resourceId);
if (
!Number.isFinite(resourceId) ||
!Number.isInteger(resourceId) ||
resourceId < 1
) {
throw new Error(
`Invalid resourceId: ${args?.resourceId}. Must be a finite positive integer.`
);
}
// Get resource based on the resource type
const uri =View on GitHub (pinned to 76d64c822f)
Solutions
- Let the tool's input schema do its job: omit `resourceType` to get the `"Text"` default, or pass `"Text"`/`"Blob"`.
- If invoking the handler directly in tests, pass args that satisfy GetResourceReferenceSchema.
- Keep the manual guard in sync with the zod enum so the two cannot diverge.
Example fix
// before
toolHandler({ resourceType: 'text', resourceId: 1 });
// after
toolHandler({ resourceType: 'Text', resourceId: 1 }); Defensive patterns
Strategy: type-guard
Validate before calling
import { RESOURCE_TYPES } from '../resources/templates.js';
// the tool's zod schema already enforces this; rely on schema-routed calls
const args = GetResourceReferenceSchema.parse(rawArgs); // throws ZodError before runtime guard Type guard
function isResourceType(v: unknown): v is 'Text' | 'Blob' {
return v === 'Text' || v === 'Blob';
} Prevention
- Let the SDK route args through GetResourceReferenceSchema; don't call the handler with raw objects.
- In tests, build args via schema.parse so they match real routing.
- Keep the manual guard and the zod enum in sync if you refactor.
When it happens
Trigger: Calling the `get-resource-reference` tool with a `resourceType` outside `"Text"`/`"Blob"` — typically only reachable if the tool is invoked with raw unvalidated args (bypassing zod parse) or if RESOURCE_TYPES is mutated. Normal SDK-routed calls go through the schema first.
Common situations: Direct unit tests invoking the handler with crafted args, schema bypass in custom transports, or a future refactor that drops the zod enum while keeping the manual guard.
Related errors
- Invalid resourceId: ${args?.resourceId}. Must be a finite po
- Unknown outputType: ${outputType}
- Invalid resourceType: ${args?.resourceType}. Must be ${RESOU
- Invalid resourceId: ${args?.resourceId}. Must be a finite po
- Unknown resource: ${uri.toString()}
AI-assisted analysis of modelcontextprotocol/servers@76d64c822f (2026-08-12).
Data as JSON: /api/errors/d946901940b8ab60.
Report an issue: GitHub.