modelcontextprotocol/servers · error · Error

Invalid resourceId: ${args?.resourceId}. Must be a finite po

Error message

Invalid resourceId: ${args?.resourceId}. Must be a finite positive integer.

What it means

Thrown by the `get-resource-reference` tool when `resourceId` is not a finite positive integer. The zod schema declares `z.number().default(1)` but does NOT enforce `.int()` or `.positive()`, so non-integer or non-positive numbers can pass the schema and hit this runtime guard.

Source

Thrown at src/everything/tools/get-resource-reference.ts:72

 */
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 =
      resourceType === RESOURCE_TYPE_TEXT
        ? textResourceUri(resourceId)
        : blobResourceUri(resourceId);
    const resource =
      resourceType === RESOURCE_TYPE_TEXT
        ? textResource(uri, resourceId)
        : blobResource(uri, resourceId);

    return {
      content: [
        {
          type: "text",

View on GitHub (pinned to 76d64c822f)

Solutions

  1. Pass `resourceId` as a positive integer (>= 1), or omit it to use the default of 1.
  2. Tighten the schema to `z.number().int().positive()` so invalid values are rejected before this guard.
  3. Normalize ids client-side: `Math.max(1, Math.floor(Number(id)))`.

Example fix

// before (schema lets a float through, runtime guard rejects it)
resourceId: z.number().default(1)
// after (reject at schema boundary, runtime guard becomes redundant)
resourceId: z.number().int().positive().default(1)
Defensive patterns

Strategy: validation

Validate before calling

function normalizeResourceId(v: unknown): number {
  const n = Math.floor(Number(v));
  return Number.isFinite(n) && n >= 1 ? n : 1;
}

Type guard

function isPositiveInt(n: unknown): n is number {
  return typeof n === 'number' && Number.isFinite(n) && Number.isInteger(n) && n >= 1;
}

Prevention

When it happens

Trigger: Calling `get-resource-reference` with `resourceId` of `0`, a negative number, a float like `1.5`, `NaN`, `Infinity`, or a non-numeric string coerced through `Number()`. The schema's `.default(1)` means omission is safe; only explicit bad values trigger it.

Common situations: Clients passing a zero-based index, a float id, or a string id (zod `.number()` rejects strings at the schema layer, but if the schema is bypassed `Number("x")` -> NaN hits here). A known gap: the schema lacks `.int().positive()`, so the manual check is the real enforcement.

Related errors


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