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

  1. Ensure the root returns/renders a static JSX element or fragment with real source text
  2. Reformat/rewrite the file so the composition root is literal JSX, then re-run
  3. 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

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


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)