remotion-dev/remotion · error · Error

A value which is not a Zod schema was passed to `schema`

Error message

A value which is not a Zod schema was passed to `schema`

What it means

When the Render Modal's schema editor resolves a composition's `schema` prop, `resolveCompositionSchema()` accepts any explicit value but verifies it duck-types as Zod (`safeParse` must be a function, packages/studio/src/components/RenderModal/SchemaEditor/infer-zod-schema-from-value.ts:127). If you passed something truthy that is not a Zod schema instance — a plain object, a schema builder like `z.object` un-applied, or a Zod namespace — Studio throws this error instead of rendering the props editor.

Source

Thrown at packages/studio/src/components/RenderModal/SchemaEditor/infer-zod-schema-from-value.ts:129

	explicitSchema,
	defaultProps,
	z,
	zodTypes,
}: {
	readonly explicitSchema: unknown;
	readonly defaultProps: Record<string, unknown>;
	readonly z: ZodNamespace | null;
	readonly zodTypes: ZodTypesType | null;
}): ResolvedCompositionSchema {
	if (!z) {
		return 'no-zod';
	}

	if (explicitSchema) {
		if (
			typeof (explicitSchema as {safeParse?: unknown}).safeParse !== 'function'
		) {
			throw new Error(
				'A value which is not a Zod schema was passed to `schema`',
			);
		}

		return explicitSchema as AnyZodSchema;
	}

	if (Object.keys(defaultProps).length === 0) {
		return 'no-schema';
	}

	return inferZodSchemaFromValue({
		value: defaultProps,
		z,
		zodTypes,
		path: [],
	});
}

View on GitHub (pinned to 10db9de073)

Solutions

  1. Pass an actual Zod schema: wrap fields with `z.object({...})` and pass the result (`schema={z.object({title: z.string()})}`).
  2. Sanity-check before assigning: `typeof schema.safeParse === 'function'` must hold.
  3. If using a custom/aliased zod instance or version (zod/v4, zod-mini), make sure the value passed is a schema instance from that same library, not a config object or namespace.

Example fix

// before
<Composition schema={{title: z.string(), count: z.number()}} ... />

// after
<Composition schema={z.object({title: z.string(), count: z.number()})} ... />
Defensive patterns

Strategy: type-guard

Validate before calling

import {z} from 'zod';

const schemaValue = z.object({title: z.string()});
if (typeof schemaValue.safeParse !== 'function') {
  throw new TypeError('schema must be a Zod schema instance');
}
// safe to pass to <Composition schema={schemaValue}>

Type guard

import type {ZodType} from 'zod';

const isZodSchema = (value: unknown): value is ZodType =>
  typeof value === 'object' &&
  value !== null &&
  typeof (value as {safeParse?: unknown}).safeParse === 'function';

Prevention

When it happens

Trigger: A `<Composition schema={...}>` (or `<Still>`) whose value is truthy but has no `safeParse` method: e.g. `schema={{title: z.string()}}` (plain object of fields), `schema={z.object}` (the factory, not its result), or `schema={zodNamespace}`. The throw happens when Studio opens/renders the schema editor for that composition.

Common situations: Confusing the shape object with a wrapped schema; passing JSON Schema instead of Zod; importing two different schema libraries or a custom `z` namespace whose values are not Zod types; refactors that accidentally pass `defaultProps`-style objects as `schema`.

Related errors


AI-assisted analysis of remotion-dev/remotion@10db9de073 (2026-08-22). Data as JSON: /api/errors/40eb8da6914c62b6. Report an issue: GitHub.