{"record":{"id":"9903d0a5cc2477b6","repo":"remotion-dev/remotion","slug":"could-not-locate-the-composition-opening-element","errorCode":null,"errorMessage":"Could not locate the composition opening element","messagePattern":"Could not locate the composition opening element","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/studio-codemods/src/composition-source-edits.ts","lineNumber":221,"sourceCode":"\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`Could not locate the \"${update.name}\" attribute`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tchangesMade.push({\n\t\t\t\t\t\t\tdescription: `Replaced ${update.description}`,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst missingMetadata = metadata.filter(\n\t\t\t\t\t\t(item) => item.value !== null && !existingMetadata.has(item.name),\n\t\t\t\t\t);\n\t\t\t\t\tif (missingMetadata.length > 0) {\n\t\t\t\t\t\tconst {openingElement} = element;\n\t\t\t\t\t\tif (!openingElement.loc || !openingElement.name.loc) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t'Could not locate the composition opening element',\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst openingEnd = recastLocToOffset(input, openingElement.loc.end);\n\t\t\t\t\t\tconst closingStart =\n\t\t\t\t\t\t\topeningEnd - (openingElement.selfClosing ? 2 : 1);\n\t\t\t\t\t\tconst lastAttribute = openingElement.attributes.findLast(\n\t\t\t\t\t\t\t(candidate) => candidate.loc,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst anchor =\n\t\t\t\t\t\t\tlastAttribute?.loc?.end ?? openingElement.name.loc.end;\n\t\t\t\t\t\tconst anchorOffset = recastLocToOffset(input, anchor);\n\t\t\t\t\t\tconst rendered = missingMetadata.map(\n\t\t\t\t\t\t\t(item) => `${item.name}={${item.value}}`,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (input.slice(anchorOffset, closingStart).includes('\\n')) {","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/studio-codemods/src/composition-source-edits.ts#L203-L239","documentation":"When metadata attributes (fps/durationInFrames/width/height) are missing from the composition, the codemod inserts them anchored at the opening element. If the openingElement or its name node lacks loc, the insertion offset cannot be computed and it throws.","triggerScenarios":"update-composition-metadata codemod on a matching <Composition> where required metadata attributes are absent and element.openingElement.loc or openingElement.name.loc is undefined (synthesized opening element without source locations).","commonSituations":"Composition JSX generated by earlier codemods or codegen that didn't preserve recast location data.","solutions":["Re-parse the original file and re-run the codemod","Persist and reformat the file so the <Composition> tag is literal source, then retry","Add the missing attributes manually"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"if (!/<Composition[\\s\\S]*?id=/.test(input)) throw new Error('Composition opening element must be literal source');","typeGuard":"const openingHasLoc = (el: any) => el.openingElement?.loc != null && el.openingElement.name?.loc != null;","tryCatchPattern":"try {\n  editCompositionInSource({input, codeMod});\n} catch (e) {\n  if ((e as Error).message.includes('Could not locate the composition opening element')) {\n    // reparse from original source or add the missing attributes manually\n  }\n}","preventionTips":["Keep the <Composition> opening tag as literal source text","Include all metadata attributes inline so the insert path is rarely used","Persist and reformat files between chained codemod steps"],"tags":["codemod","jsx","source-locations"],"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"}