remotion-dev/remotion · error · Error
<Composition> mounted inside another composition. See https:
Error message
<Composition> mounted inside another composition. See https://remotion.dev/docs/wrong-composition-mount for help.
What it means
Thrown by <Composition> when it mounts inside another <Composition> (not a Player). Composition registration must happen at the root; nesting a <Composition> inside another composition's render tree is invalid and would double-register/loop the render graph.
Source
Thrown at packages/core/src/Composition.tsx:178
const environment = useRemotionEnvironment();
const canUseComposition = useContext(CanUseRemotionHooks);
// Record seen composition IDs as early as possible so that overlays can access them
if (typeof window !== 'undefined') {
window.remotion_seenCompositionIds = Array.from(
new Set([...(window.remotion_seenCompositionIds ?? []), id]),
);
}
if (canUseComposition) {
if (isPlayer) {
throw new Error(
'<Composition> was mounted inside the `component` that was passed to the <Player>. See https://remotion.dev/docs/wrong-composition-mount for help.',
);
}
throw new Error(
'<Composition> mounted inside another composition. See https://remotion.dev/docs/wrong-composition-mount for help.',
);
}
const {folderName, parentName} = useContext(FolderContext);
const stack =
(compProps as {readonly _remotionInternalStack?: string})
._remotionInternalStack ?? null;
const componentFromProps =
'component' in compProps ? compProps.component : null;
useEffect(() => {
// Ensure it's a URL safe id
if (!id) {
throw new Error('No id for composition passed.');
}
validateCompositionId(id);View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Register each <Composition> only at the top level of the <Root>.
- To combine videos, render the inner composition's component directly (extracted), not the <Composition> wrapper.
- See https://remotion.dev/docs/wrong-composition-mount.
Example fix
// before
<Composition id="Outer" component={() => (
<>
<MyInnerVideo />
<Composition id="Inner" component={Inner} .../> // throws
</>
)} .../>
// after
<Composition id="Outer" component={() => <MyInnerVideo />} .../>
<Composition id="Inner" component={Inner} .../> // registered at root, not nested Defensive patterns
Strategy: type-guard
Validate before calling
// Ensure each <Composition> is registered only at the <Root> level, // and composition components render plain JSX, never <Composition>.
Type guard
null
Try / catch
null
Prevention
- Register every <Composition> directly inside <Composition Root>.
- Extract reusable video components and render them, not <Composition> wrappers.
- Lint against rendering <Composition> inside another component.
When it happens
Trigger: Rendering a <Composition> element within the JSX of the `component` prop of another <Composition>. The CanUseRemotionHooks context (non-player branch) detects this and throws.
Common situations: Trying to compose one video inside another by embedding <Composition> JSX; reusing a root component as a child component; misunderstanding the registration-vs-render boundary.
Related errors
- <Composition> was mounted inside the `component` that was pa
- <Clipper> has been removed as of Remotion v4.0.228. The nati
- TimelineContext is not available. This hook must be used ins
- useCurrentFrame() can only be called inside a component that
- A value of `undefined` was passed to the `component` prop. C
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/f16bedbb5d0b09e7.
Report an issue: GitHub.