vercel/ai · error · MCPClientError

maxRetries must be an integer

Error message

maxRetries must be an integer

What it means

Thrown by prepareMaxRetries (via MCPClientError) when a non-integer maxRetries value is passed to the MCPClient constructor. maxRetries controls how many times failed tool calls are retried and must be a whole number.

Source

Thrown at packages/mcp/src/tool/mcp-client.ts:145

      statusCode >= 500
    );
  }

  if (MCPClientError.isInstance(error) && error.code != null) {
    return false;
  }

  const errorCode = getStringErrorCode(error);
  return errorCode != null && DEFAULT_RETRY_ERROR_CODES.includes(errorCode);
}

function prepareMaxRetries(maxRetries: number | undefined): number {
  if (maxRetries == null) {
    return DEFAULT_MAX_TOOL_CALL_RETRIES;
  }

  if (!Number.isInteger(maxRetries)) {
    throw new MCPClientError({
      message: 'maxRetries must be an integer',
    });
  }

  if (maxRetries < 0) {
    throw new MCPClientError({
      message: 'maxRetries must be >= 0',
    });
  }

  return maxRetries;
}

function getEffectiveTimeout({
  timeout,
  maxTotalTimeout,
}: RequestOptions): number | undefined {
  if (timeout == null) {

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Pass an integer: Math.floor/parseInt your value before constructing the client.
  2. Validate config values at startup (Number.isInteger check).
  3. Omit maxRetries entirely to use DEFAULT_MAX_TOOL_CALL_RETRIES.

Example fix

// before
new MCPClient({ ..., maxRetries: Number(process.env.MCP_RETRIES) }); // NaN
// after
new MCPClient({ ..., maxRetries: Number.parseInt(process.env.MCP_RETRIES ?? '2', 10) });
Defensive patterns

Strategy: validation

Validate before calling

const maxRetries = Number(process.env.MCP_RETRIES);
if (!Number.isInteger(maxRetries)) {
  throw new Error('MCP_RETRIES must be an integer');
}

Type guard

function isValidMaxRetries(v: unknown): v is number {
  return typeof v === 'number' && Number.isInteger(v);
}

Try / catch

try {
  const client = await createMCPClient({ transport, maxRetries: rawRetries });
} catch (e) {
  if (MCPClientError.isInstance(e) && e.message === 'maxRetries must be an integer') {
    // rebuild with default options
  } else throw e;
}

Prevention

When it happens

Trigger: Creating an MCP client with maxRetries set to a fractional number (e.g. 2.5), NaN, or Infinity instead of an integer (undefined/null is allowed and falls back to the default).

Common situations: Reading maxRetries from a config/env variable or CLI arg and forgetting to parse it with Number/parseInt; computing a fractional value like retries/2; passing NaN from an unparseable env string.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/cbd11ae050b4eaa4. Report an issue: GitHub.