vercel/ai · error

Invalid n: expected a positive integer, received ${JSON.stri

Error message

Invalid n: expected a positive integer, received ${JSON.stringify(n)}.

What it means

startVideo validates that n is a positive integer before starting the job. Anything else (0, negative, fractional, NaN, non-number) throws this validation Error with the JSON of the received value. This guards against building an invalid provider request.

Source

Thrown at packages/ai/src/generate-video/start-video.ts:142

  >;
  generateAudio?: boolean;
  providerOptions?: ProviderOptions;
  maxRetries?: number;
  abortSignal?: AbortSignal;
  headers?: Record<string, string>;
  webhookUrl?: string;
}): Promise<StartVideoResult> {
  const model = resolveVideoModel(modelArg);

  if (model.doStart == null) {
    throw new Error(
      `Video model ${model.modelId} does not implement doStart. ` +
        'Use generateVideo for models without an asynchronous start/status flow.',
    );
  }

  if (!Number.isInteger(n) || n < 1) {
    throw new Error(
      `Invalid n: expected a positive integer, received ${JSON.stringify(n)}.`,
    );
  }

  // A start yields one operation covering all n videos: refuse to silently
  // exceed a known per-call limit instead of splitting into several starts.
  const knownMaxVideosPerCall =
    maxVideosPerCall ??
    (typeof model.maxVideosPerCall === 'function'
      ? await model.maxVideosPerCall({ modelId: model.modelId })
      : model.maxVideosPerCall);
  if (knownMaxVideosPerCall != null && n > knownMaxVideosPerCall) {
    throw new Error(
      `Video model ${model.modelId} supports at most ${knownMaxVideosPerCall} video(s) per call, ` +
        `but ${n} were requested. Split the batch across multiple startVideo calls.`,
    );
  }

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Pass a positive integer for n (>= 1).
  2. Clamp/round computed values: Math.max(1, Math.round(x)).
  3. Validate input before calling startVideo.
  4. Default undefined n explicitly to 1.

Example fix

// before
const n = Number(userInput); // could be NaN/0/1.5
await experimental_startVideo({ model, prompt, n });
// after
const n = Math.max(1, Math.round(Number(userInput) || 1));
await experimental_startVideo({ model, prompt, n });
Defensive patterns

Strategy: validation

Validate before calling

function assertValidN(n) {
  if (!Number.isInteger(n) || n < 1) throw new Error(`Invalid n: ${JSON.stringify(n)}`);
}
assertValidN(n);

Type guard

function isValidN(n) {
  return typeof n === 'number' && Number.isInteger(n) && n >= 1;
}

Try / catch

try {
  await experimental_startVideo({ model, prompt, n });
} catch (e) {
  if (e.message.startsWith('Invalid n')) {
    // coerce/fix n and retry
    await experimental_startVideo({ model, prompt, n: 1 });
  }
}

Prevention

When it happens

Trigger: experimental_startVideo called with n = 0, negative n, non-integer values like 1.5, NaN, or a string/undefined n.

Common situations: n computed from dynamic input (user-supplied count, array length of empty list, parseFloat output); default value not applied so n is undefined.

Related errors


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