remotion-dev/remotion · error
Could not locate the composition insertion target
Error message
Could not locate the composition insertion target
What it means
For a new-composition codemod, editCompositionInSource finds a freshly generated (location-less) JSX element and then determines the insertion root: either the surrounding element (if it has real source locations) or its first located JSXElement/JSXFragment child. If neither exists, there is no anchor in the original source to insert the new composition, so it throws.
Solutions
- Ensure the root returns/renders a static JSX element or fragment with real source text
- Reformat/rewrite the file so the composition root is literal JSX, then re-run
- Insert the new <Composition> manually
Example fix
// before: export const RemotionRoot = () => getCompositions().map(c => render(c))
// after:
export const RemotionRoot = () => (
<>
<Composition id="MyComp" component={MyComp} ...
</>
); Defensive patterns
Strategy: validation
Validate before calling
const rootIsStaticJsx = /(<\s*[A-Za-z<>/>]|<>\s)/.test(rootFileSource);
if (!/<[A-Z][\w.]*[\s/>]/.test(rootFileSource)) throw new Error('Root file must render a literal JSX element'); Type guard
const isLocatedRoot = (n: any): boolean => n && (n.type === 'JSXElement' || n.type === 'JSXFragment') && n.loc != null;
Try / catch
try {
editCompositionInSource({input, codeMod});
} catch (e) {
if ((e as Error).message.includes('Could not locate the composition insertion target')) {
// rewrite Root to return literal JSX, then retry
}
} Prevention
- Keep RemotionRoot returning literal <Composition> elements
- Avoid building the composition list programmatically
- Format the Root file with prettier before running add-composition codemods
When it happens
Trigger: The visitNode pass finds a generated JSX element but its container node has no loc and none of the container's children with type JSXElement have loc either (no root with source locations).
Common situations: The target root file is not normal JSX (e.g. the composition list is built programmatically or the file was already heavily machine-generated), leaving no parseable anchor element.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Cannot duplicate a JSX element without a source location
- Cannot duplicate JSX element with no parent
- Cannot split a JSX sequence without a source location
- Cannot split JSX sequence with no parent
- Component style must be an object to add a position
AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18).
Data as JSON: /api/errors/aa48f4939472e391.
Report an issue: GitHub.
Appendix: source
Thrown at packages/studio-codemods/src/composition-source-edits.ts:105
);
if (attribute?.type === 'JSXAttribute') {
attribute.value = recast.types.builders.jsxExpressionContainer(
recast.types.builders.identifier(component),
);
}
}
// A newly generated fragment wraps the existing lone root.
const root = node.loc
? node
: node.children?.find(
(child) => child.type === 'JSXElement' && child.loc,
);
if (
!root ||
(root.type !== 'JSXElement' && root.type !== 'JSXFragment')
) {
throw new Error('Could not locate the composition insertion target');
}
edits.push(
getInsertionRootSourceEdit({
input,
insertion: printInsertedJsx({
element: inserted,
input,
prettierConfigOverride: null,
}),
root,
nullRoot: null,
prettierConfigOverride: null,
insertInside: Boolean(node.loc),
}),
);
return false;
},View on GitHub (pinned to 46a3a6bf13)