remotion-dev/remotion · error · TypeError

The cropLeft, cropRight, cropTop and cropBottom props of <Se

Error message

The cropLeft, cropRight, cropTop and cropBottom props of <Sequence /> are only supported with layout="absolute-fill".

What it means

Thrown by <Sequence> when `layout="none"` is set and any of cropLeft, cropRight, cropTop, or cropBottom is also passed. Cropping is implemented as a CSS clip on the absolutely-positioned wrapper div that layout="absolute-fill" provides; with layout="none" there is no wrapper to clip against, so crop props would be silently ignored. The error prevents that silent no-op.

Source

Thrown at packages/core/src/Sequence.tsx:185

	const parentSequence = useContext(SequenceContext);
	const cumulatedFrom = parentSequence
		? parentSequence.cumulatedFrom + parentSequence.relativeFrom
		: 0;
	const nonce = useNonce();

	if (layout !== 'absolute-fill' && layout !== 'none') {
		throw new TypeError(
			`The layout prop of <Sequence /> expects either "absolute-fill" or "none", but you passed: ${layout}`,
		);
	}

	const cropProps = {cropLeft, cropRight, cropTop, cropBottom};
	const hasCropProp = Object.values(cropProps).some(
		(value) => value !== undefined,
	);

	if (layout === 'none' && hasCropProp) {
		throw new TypeError(
			'The cropLeft, cropRight, cropTop and cropBottom props of <Sequence /> are only supported with layout="absolute-fill".',
		);
	}

	validateSequenceCrop(cropProps);
	const {
		left: resolvedCropLeft,
		right: resolvedCropRight,
		top: resolvedCropTop,
		bottom: resolvedCropBottom,
	} = resolveSequenceCrop(cropProps);
	// @ts-expect-error
	if (layout === 'none' && typeof other.style !== 'undefined') {
		throw new TypeError(
			'If layout="none", you may not pass a style. Passed: ' +
				// @ts-expect-error
				JSON.stringify(other.style),
		);

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Drop the cropLeft/cropRight/cropTop/cropBottom props when using `layout="none"`.
  2. If you need cropping, switch to `layout="absolute-fill"` (or omit layout).
  3. If you need layout="none" and clipping, apply the clip in your own wrapper element via CSS.
  4. Audit shared Sequence config objects that get spread into both cropped and non-cropped usages.

Example fix

// before
<Sequence layout="none" cropLeft={100} cropRight={100} durationInFrames={30} />
// after
<Sequence layout="none" durationInFrames={30} />
Defensive patterns

Strategy: validation

Validate before calling

const cropProps = {cropLeft, cropRight, cropTop, cropBottom};
const hasCrop = Object.values(cropProps).some((v) => v !== undefined);
if (layout === 'none' && hasCrop) {
  throw new TypeError('crop props require layout="absolute-fill"');
}

Type guard

const isCropPropFree = (props: Record<string, unknown>): boolean =>
  ['cropLeft','cropRight','cropTop','cropBottom'].every((k) => props[k] === undefined);

Prevention

When it happens

Trigger: Passing both `layout="none"` and any crop prop on the same <Sequence>; copy-pasting a cropped <Sequence> and switching layout to 'none' without removing crop props.

Common situations: Refactoring a Sequence to embed it in a custom layout (layout="none") while forgetting the crop config; combining sequence composition with manual cropping.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/6b78a346c7166278. Report an issue: GitHub.