remotion-dev/remotion · error · Error

animationData should be provided as an object. If you only h

Error message

animationData should be provided as an object. If you only have the path to the JSON file, load it and pass it as animationData. See https://remotion.dev/docs/lottie/lottie#example for more information.

What it means

The @remotion/lottie Lottie component requires animationData as a parsed JavaScript object (the Lottie JSON already JSON.parse'd). It throws if `typeof animationData !== 'object'`, catching the common mistake of passing a file path string or a raw JSON string.

Source

Thrown at packages/lottie/src/Lottie.tsx:27

/**
 * @description	Part of the @remotion/lottie package.
 * @see [Documentation](https://www.remotion.dev/docs/lottie/lottie)
 */
export const Lottie = ({
	animationData,
	className,
	direction,
	loop,
	playbackRate,
	style,
	onAnimationLoaded,
	renderer,
	preserveAspectRatio,
	assetsPath,
}: LottieProps) => {
	if (typeof animationData !== 'object') {
		throw new Error(
			'animationData should be provided as an object. If you only have the path to the JSON file, load it and pass it as animationData. See https://remotion.dev/docs/lottie/lottie#example for more information.',
		);
	}

	validatePlaybackRate(playbackRate);
	validateLoop(loop);

	const animationRef = useRef<AnimationItem | null>(null);
	const currentFrameRef = useRef<number | null>(null);
	const containerRef = useRef<HTMLDivElement>(null);

	const onAnimationLoadedRef =
		useRef<LottieProps['onAnimationLoaded']>(onAnimationLoaded);
	onAnimationLoadedRef.current = onAnimationLoaded;
	const {delayRender, continueRender} = useDelayRender();

	const [handle] = useState(() =>
		delayRender('Waiting for Lottie animation to load'),

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Import the JSON file as an object (most bundlers do this by default): `import animationData from './anim.json'`.
  2. If fetching at runtime, await res.json() before rendering the <Lottie>.
  3. If you only have a path string, fetch + JSON.parse it first.
  4. Confirm animationData is truthy before rendering to avoid passing undefined.

Example fix

// before
<Lottie animationData={'/lotties/anim.json'} />
// after
import animData from './anim.json';
// ...
<Lottie animationData={animData} />
Defensive patterns

Strategy: type-guard

Validate before calling

function isAnimationObject(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null && !Array.isArray(v);
}
if (!isAnimationObject(animationData)) {
  throw new Error('Pass a parsed Lottie JSON object, not a path or string');
}

Type guard

const isLottieData = (v: unknown): v is Record<string, unknown> =>
  typeof v === 'object' && v !== null && 'v' in v && 'fr' in v;

Try / catch

try {
  return <Lottie animationData={animationData} />;
} catch (e) {
  if (/animationData should be provided as an object/i.test((e as Error).message)) {
    const parsed = await (await fetch(src)).json();
    return <Lottie animationData={parsed} />;
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a URL/path string instead of the loaded object; passing a JSON string instead of parsing it first; passing undefined because the import failed; passing a Promise or fetch Response.

Common situations: Using import animationData from './anim.json' but the bundler returned a string; fetching the Lottie JSON at runtime and forgetting to call .json(); mixing up the path-based API (lottie-web) with this component.

Related errors


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