remotion-dev/remotion · error

Could not find ${getCompositionOrFolderLabel(transformation.

Error message

Could not find ${getCompositionOrFolderLabel(transformation.source)} as a direct JSX child

What it means

moveCompositionOrFolder implements the Studio codemod that moves a composition or folder within the Root JSX. It scans all JSX elements for a direct JSX child matching the transformation source (composition id or folder name+parent). If no match is found as a direct child of a JSXElement/JSXFragment, it throws 'Could not find <label> as a direct JSX child'.

Source

Thrown at packages/studio-codemods/src/recast-mods.ts:639

					astPath.get('children', index) as recast.types.NodePath,
				);
			}
		}

		if (folderName !== null) {
			folderStack.pop();
		}
	};

	recast.types.visit(file, {
		visitJSXElement(astPath) {
			visitJsxElement(astPath as unknown as recast.types.NodePath);
			return false;
		},
	});

	if (source === null) {
		throw new Error(
			`Could not find ${getCompositionOrFolderLabel(transformation.source)} as a direct JSX child`,
		);
	}

	const sourceItem = source as LocatedItem;
	if (
		(transformation.destination.type === 'before' ||
			transformation.destination.type === 'after') &&
		target === null
	) {
		throw new Error(
			`Could not find ${getCompositionOrFolderLabel(transformation.destination.target)} as a reorder target`,
		);
	}

	if (
		transformation.destination.type === 'folder' &&
		destinationFolder === null

View on GitHub (pinned to a6a7485a9a)

Solutions

  1. Verify the composition id or folder name/parent in the transformation matches the actual JSX in the Root file (check spelling and nesting path)
  2. Ensure the composition is a direct child of a JSXElement or fragment in the targeted file (remove wrapper components/indirection)
  3. Reopen/reload the Studio so the codemod targets the current file contents after any manual edits
  4. If the composition lives in another Root file, run the move from the correct file/context

Example fix

// before (codemod asked to move id="MyComp" but file contains)
<Composition id="my-comp" ... />
// after
<Composition id="MyComp" ... />  // align the id (or retry the move) so source matches a direct JSX child
Defensive patterns

Strategy: validation

Validate before calling

const existsAsDirectChild = (fileAst: File, compositionId: string): boolean =>
  recast.types.visit(fileAst, {
    visitJSXElement(p) {
      const parent = p.parentPath?.node;
      const isDirect = parent && ['JSXElement','JSXFragment'].includes(parent.type);
      if (isDirect && getCompositionIdFromJSXElement(p.node as JSXElement) === compositionId) return false;
      this.traverse(p);
      return false;
    },
  }) ?? false;

Type guard

const isDirectJsxChild = (node: JSXElement, parent: {type: string; children: unknown[]} | undefined): boolean =>
  (parent?.type === 'JSXElement' || parent?.type === 'JSXFragment') && parent.children.includes(node);

Try / catch

try {
  applyCodemod(file, transformation);
} catch (err) {
  if (err instanceof Error && err.message.includes('as a direct JSX child')) {
    console.warn(`Move skipped: ${err.message}. Check the composition/folder still exists in this file.`);
    return {applied: false};
  }
  throw err;
}

Prevention

When it happens

Trigger: Running a move codemod whose source composition id or folder name/parent does not match any direct JSX child in the file — e.g. the composition was renamed/deleted, lives in a different file, is conditionally rendered, or the folder path (parentName/folderName) doesn't match the actual nesting.

Common situations: Stale Studio state after renaming a composition in code without reloading; composition defined in another file than the one the codemod targets; the element is nested deeper than direct-child level via wrappers; duplicate folder names causing path mismatch.

Related errors


AI-assisted analysis of remotion-dev/remotion@a6a7485a9a (2026-09-02). Data as JSON: /api/errors/85ff95e605b6f2b2. Report an issue: GitHub.