remotion-dev/remotion · error · Error

You passed ${entryPoint} as your entry point, but this file

Error message

You passed ${entryPoint} as your entry point, but this file does not contain "registerRoot". You should use the file that calls registerRoot() as the entry point. To ignore this error, pass "ignoreRegisterRootWarning" to bundle(). This error cannot be ignored on the CLI.

What it means

validateEntryPoint reads the entry-point file and checks that its text contains the literal 'registerRoot'. Every Remotion entry point must call registerRoot() to register the root composition; passing a different file (a component, a utils module, the wrong index) is a classic mistake. The check is a substring scan, and it can be bypassed only by passing ignoreRegisterRootWarning (not available on the CLI).

Source

Thrown at packages/bundler/src/bundle.ts:254

		const exists = fs.existsSync(possibleFile);
		if (exists) {
			return path.dirname(possibleFile);
		}

		currentDir = path.dirname(currentDir);
	}

	return null;
};

const findClosestPackageJsonFolder = (currentDir: string): string | null => {
	return findClosestFolderWithItem(currentDir, 'package.json');
};

const validateEntryPoint = async (entryPoint: string) => {
	const contents = await promises.readFile(entryPoint, 'utf8');
	if (!contents.includes('registerRoot')) {
		throw new Error(
			[
				`You passed ${entryPoint} as your entry point, but this file does not contain "registerRoot".`,
				'You should use the file that calls registerRoot() as the entry point.',
				'To ignore this error, pass "ignoreRegisterRootWarning" to bundle().',
				'This error cannot be ignored on the CLI.',
			].join(' '),
		);
	}
};

export const internalBundle = async (
	actualArgs: MandatoryBundleOptions,
): Promise<string> => {
	const entryPoint = path.resolve(process.cwd(), actualArgs.entryPoint);
	const resolvedRemotionRoot =
		actualArgs?.rootDir ??
		findClosestPackageJsonFolder(entryPoint) ??
		process.cwd();

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Point entryPoint at the file that actually calls registerRoot() (usually src/Root.tsx or src/index.ts).
  2. If you register the root indirectly and want to silence the check, pass ignoreRegisterRootWarning: true to bundle() (note: not available on the CLI).
  3. Confirm the file text contains 'registerRoot' literally (grep it).
  4. Make sure the path resolves (a different 'file not found' would surface as an FS error, not this message).

Example fix

// before
bundle({entryPoint: './src/MyVideo.tsx'}); // MyVideo.tsx only exports a component

// after
bundle({entryPoint: './src/index.ts'}); // index.ts contains registerRoot(<Root/>);
Defensive patterns

Strategy: validation

Validate before calling

import {readFile} from 'node:fs/promises';
const assertEntryPointHasRegisterRoot = async (entryPoint: string) => {
  const src = await readFile(entryPoint, 'utf8');
  if (!src.includes('registerRoot')) {
    throw new Error(`${entryPoint} does not contain registerRoot`);
  }
};
// or pass ignoreRegisterRootWarning when you register indirectly:
// bundle({entryPoint, ignoreRegisterRootWarning: true})

Try / catch

try {
  await bundle({entryPoint});
} catch (err) {
  if (String(err?.message ?? '').includes('does not contain "registerRoot"')) {
    // point the user at the file that calls registerRoot()
  } else throw err;
}

Prevention

When it happens

Trigger: Pointing entryPoint at a <Composition>-only component file, a barrel/index file, or any file that doesn't textually contain 'registerRoot'. File is readable but lacks the call.

Common situations: New users pass their Composition component instead of the Root file; code-splitting moved registerRoot elsewhere; renamed the function or referenced it indirectly; pointing at a TypeScript definition file.

Related errors


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