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

  1. Let the tool's input schema do its job: omit `resourceType` to get the `"Text"` default, or pass `"Text"`/`"Blob"`.
  2. If invoking the handler directly in tests, pass args that satisfy GetResourceReferenceSchema.
  3. 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

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


AI-assisted analysis of modelcontextprotocol/servers@76d64c822f (2026-08-12). Data as JSON: /api/errors/d946901940b8ab60. Report an issue: GitHub.