{"record":{"id":"2a6a6054a4c6cfe8","repo":"remotion-dev/remotion","slug":"could-not-find-a-root-jsx-element","errorCode":null,"errorMessage":"Could not find a root JSX element","messagePattern":"Could not find a root JSX element","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/studio-codemods/src/recast-mods.ts","lineNumber":471,"sourceCode":"}) => {\n\tfolderElement.openingElement.selfClosing = false;\n\tfolderElement.closingElement = folderElement.closingElement ?? {\n\t\ttype: 'JSXClosingElement',\n\t\tname: folderElement.openingElement.name,\n\t};\n\tfolderElement.children.push(stripParenthesizedExtra(element));\n};\n\nconst appendElementToRoot = ({\n\telement,\n\treturnStatement,\n}: {\n\telement: JSXElement;\n\treturnStatement: ReturnStatement;\n}) => {\n\tconst {argument} = returnStatement;\n\tif (argument?.type !== 'JSXFragment' && argument?.type !== 'JSXElement') {\n\t\tthrow new Error('Could not find a root JSX element');\n\t}\n\n\tif (argument.type === 'JSXFragment') {\n\t\t(argument.children as JSXFragment['children']).push(\n\t\t\tstripParenthesizedExtra(element),\n\t\t);\n\t} else {\n\t\treturnStatement.argument = wrapInJsxFragment([\n\t\t\targument as unknown as JSXElement,\n\t\t\telement,\n\t\t]) as never;\n\t}\n};\n\nconst getEnclosingReturnStatement = (path: recast.types.NodePath) => {\n\tlet currentPath: recast.types.NodePath | null = path;\n\twhile (currentPath !== null) {\n\t\tif (","sourceCodeStart":453,"sourceCodeEnd":489,"githubUrl":"https://github.com/remotion-dev/remotion/blob/a6a7485a9aeb04219510fbe4874f8941486424df/packages/studio-codemods/src/recast-mods.ts#L453-L489","documentation":"appendElementToRoot is a recast-based codemod helper in @remotion/studio-codemods that appends a JSX element to a component's returned root. It expects the enclosing return statement's argument to be a JSXFragment or JSXElement (the root JSX). If the argument is something else (null, a call expression like createElement(), a conditional, etc.) it throws 'Could not find a root JSX element'.","triggerScenarios":"Running a move-composition/move-to-folder codemod against a Root file whose component returns a non-JSX root — e.g. return null, return createComponent(...), a conditional expression, or a return statement whose argument is missing.","commonSituations":"Root files written with React.createElement instead of JSX; early `return null;` before the JSX return; commented-out or generated Root files without a JSX return; files that re-export the Root from another module.","solutions":["Rewrite the Root component to return a literal JSX element or fragment: return (<>...</>)","Remove or hoist early non-JSX returns (e.g. `return null`) so the enclosing return statement yields JSX","If the root is wrapped in a conditional, extract the conditional inside a fragment: return (<>{cond ? <A/> : <B/>}</>)","Run the codemod on a file that directly contains the JSX Root rather than a re-export module"],"exampleFix":"// before\nexport const RemotionRoot = () => {\n  if (!videos.length) return null;\n  return <>{videos.map(...)}</>;\n};\n// after\nexport const RemotionRoot = () => {\n  return (<>{videos.length ? videos.map(...) : null}</>);\n};","handlingStrategy":"validation","validationCode":"const returnsJsx = /return\\s*\\(?\\s*<[A-Za-z>]/.test(componentSource);\nif (!returnsJsx) throw new Error('Root must return JSX for codemods');","typeGuard":"const isJsxReturn = (arg: unknown): arg is JSXElement | JSXFragment =>\n  arg !== null && typeof arg === 'object' &&\n  ['JSXElement', 'JSXFragment'].includes((arg as {type?: string}).type ?? '');","tryCatchPattern":"try {\n  applyCodemod(file, transformation);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Could not find a root JSX element') {\n    console.warn('Root file does not return JSX directly; skipping codemod');\n    return {applied: false};\n  }\n  throw err;\n}","preventionTips":["Keep Root components returning literal JSX (element or fragment)","Avoid early `return null` before the JSX return","Prefer JSX over React.createElement in Root files","Warn users when their Root file structure is not codemod-compatible"],"tags":["codemod","ast","jsx","recast"],"backgroundTag":"unrecognized-jsx-root","analyzedSha":"a6a7485a9aeb04219510fbe4874f8941486424df","analyzedAt":"2026-09-02T16:25:19.997Z","contentChangedAt":"2026-09-02T16:25:19.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}