remotion-dev/remotion · error

model must be a string.

Error message

model must be a string.

What it means

The tool defaults model to 'small.en' and then asserts it is a string before matching it against available Whisper models. Because the default guarantees a string in normal flow, this throw mainly protects against corrupted input state where model resolves to a non-string value that bypasses the nullish coalescing (e.g. explicit null or object).

Source

Thrown at packages/studio/src/components/WebMcp.tsx:514

							return missingOptionalPackageResult(WHISPER_WEBGPU_PACKAGE);
						}

						const assetPath = resolveAssetPath({
							assetPath: input.assetPath,
							currentContent: currentContentRef.current,
							staticFiles: staticFilesRef.current,
						});
						const fileType = getPreviewFileType(assetPath);
						if (fileType !== 'audio' && fileType !== 'video') {
							throw new Error(
								'The transcription asset must be audio or video.',
							);
						}

						const whisper = await import('@remotion/whisper-webgpu');
						const modelName = input.model ?? 'small.en';
						if (typeof modelName !== 'string') {
							throw new Error('model must be a string.');
						}

						const model = whisper
							.getAvailableModels()
							.find((candidate) => candidate.name === modelName);
						if (!model) {
							throw new Error(`Unknown Whisper model: ${modelName}.`);
						}

						const task = input.task ?? 'transcribe';
						if (task !== 'transcribe' && task !== 'translate') {
							throw new Error('task must be transcribe or translate.');
						}

						if (task === 'translate' && !model.supportsTranslation) {
							throw new Error(`${model.name} does not support translation.`);
						}

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Omit the model argument to use the 'small.en' default, or pass a valid model name string like 'small.en'.
  2. Ensure model is a string, not null or a number.
  3. Match the name against whisper.getAvailableModels() before calling.
  4. Fix the calling client's schema so model is string | undefined.

Example fix

// before
await tool.execute({assetPath: 'a.mp3', model: null});
// after
await tool.execute({assetPath: 'a.mp3'}); // defaults to 'small.en'
Defensive patterns

Strategy: type-guard

Validate before calling

if (model !== undefined && typeof model !== 'string') {
  throw new Error('model must be a string or omitted.');
}

Type guard

const isModelName = (v: unknown): v is string =>
  typeof v === 'string' && v.length > 0;

Try / catch

try {
  await transcribeTool({assetPath, model});
} catch (e) {
  if (e.message === 'model must be a string.') {
    await transcribeTool({assetPath}); // use default
  }
}

Prevention

When it happens

Trigger: Calling the WebMcp transcribe tool with input.model explicitly set to null, a number, an object, or another non-string non-undefined value.

Common situations: Agents sending JSON with null instead of omitting the field; schema-less tool callers passing wrong types; handcrafted requests with model: 2.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09). Data as JSON: /api/errors/427957c67953381c. Report an issue: GitHub.