{"record":{"id":"8e20367e1826faf3","repo":"remotion-dev/remotion","slug":"could-not-locate-the-composition-closing-tag","errorCode":null,"errorMessage":"Could not locate the composition closing tag","messagePattern":"Could not locate the composition closing tag","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/studio-codemods/src/insert-jsx-element.ts","lineNumber":2296,"sourceCode":"\t\t\t\t\tinsertion,\n\t\t\t\t}),\n\t\t\t\t`${nullIndent}${unit}</>`,\n\t\t\t\t`${nullIndent})`,\n\t\t\t].join(endOfLine),\n\t\t\tstart: nullStart,\n\t\t};\n\t}\n\n\tif (!root?.loc) {\n\t\tthrow new Error('Could not locate the composition component root');\n\t}\n\n\tif (insertInside) {\n\t\tconst closing =\n\t\t\troot.type === 'JSXFragment' ? root.closingFragment : root.closingElement;\n\t\tif (!closing?.loc) {\n\t\t\tif (root.type !== 'JSXElement' || !root.openingElement.loc) {\n\t\t\t\tthrow new Error('Could not locate the composition closing tag');\n\t\t\t}\n\n\t\t\tconst openingStart = recastLocToOffset(\n\t\t\t\tinput,\n\t\t\t\troot.openingElement.loc.start,\n\t\t\t);\n\t\t\tconst openingEnd = recastLocToOffset(input, root.openingElement.loc.end);\n\t\t\tconst openingIndent = getLineIndent({input, offset: openingStart});\n\t\t\treturn {\n\t\t\t\tstart: openingStart,\n\t\t\t\tend: openingEnd,\n\t\t\t\treplacement: [\n\t\t\t\t\tinput.slice(openingStart, openingEnd).replace(/\\s*\\/>$/, '>'),\n\t\t\t\t\tindentInsertedJsx({indent: `${openingIndent}${unit}`, insertion}),\n\t\t\t\t\t`${openingIndent}</${recast.print(root.openingElement.name).code}>`,\n\t\t\t\t].join(endOfLine),\n\t\t\t};\n\t\t}","sourceCodeStart":2278,"sourceCodeEnd":2314,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/studio-codemods/src/insert-jsx-element.ts#L2278-L2314","documentation":"For insertInside insertions the codemod must find the composition root's closing tag (closingElement/closingFragment) to compute where children end. If the closing tag has no location and the root is not a self-closing JSX element with a locatable opening tag, it cannot compute the insertion offset and throws.","triggerScenarios":"Calling the insert-JSX-element codemod with insertInside: true against a root whose closing tag is missing location info — typically malformed/recast-lost JSX, or a root that is neither a JSXElement with an openingElement.loc nor has closing tag locations.","commonSituations":"Files previously rewritten by tooling that dropped node locations; hand-minified JSX on one line missing loc data; parsing quirks where the closing element's source mapping is unavailable.","solutions":["Reformat the file with Prettier so JSX tags are well-formed and locations are stable, then rerun the codemod.","Ensure the root element has both opening and closing tags (not a corrupted/self-closing root when inserting inside).","Re-parse from a clean git state if the file was previously modified by another codemod.","If the root is self-closing, convert it to <tag></tag> form before inserting children."],"exampleFix":"// before (self-closing root, insertInside) -> throws\n<div />\n// after\n<div>\n  {/* children insert here */}\n</div>","handlingStrategy":"fallback","validationCode":"const root = findCompositionRoot(parsed);\nconst canInsertInside = Boolean(root && ((root.type === 'JSXFragment' && root.closingFragment?.loc) || (root.type === 'JSXElement' && (root.closingElement?.loc || root.openingElement?.loc))));\nif (!canInsertInside) insertAsSiblingInstead();","typeGuard":null,"tryCatchPattern":"try {\n  insertJsxElement({...opts, insertInside: true});\n} catch (e) {\n  if (e instanceof Error && e.message === 'Could not locate the composition closing tag') {\n    prettierFormat(file); // stabilize JSX locations, then retry once\n    insertJsxElement({...opts, insertInside: true});\n  } else throw e;\n}","preventionTips":["Run Prettier on files before applying JSX-inserting codemods","Use explicit open/close tags on the composition root","Re-parse from a clean state after other tooling rewrites the file"],"tags":["jsx","codemod","ast","location"],"backgroundTag":"internal-invariant-violation","analyzedSha":"46a3a6bf13ca367376ff18bbb06dae2e87e0d068","analyzedAt":"2026-09-18T00:12:20.256Z","contentChangedAt":"2026-09-18T00:12:20.256Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}