{"record":{"id":"da584a94f5f12cd7","repo":"remotion-dev/remotion","slug":"could-not-locate-the-video-element","errorCode":null,"errorMessage":"Could not locate the video element","messagePattern":"Could not locate the video element","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/studio-codemods/src/split-video-from-audio.ts","lineNumber":242,"sourceCode":"\tconst trailingWhitespace = beforeClosing.match(/[\\t ]*$/)?.[0] ?? '';\n\treturn {\n\t\tstart: closingStart - trailingWhitespace.length,\n\t\tend: closingStart - trailingWhitespace.length,\n\t\treplacement: ' muted',\n\t};\n};\n\nconst applyEditToElementSource = ({\n\tedit,\n\telement,\n\tinput,\n}: {\n\tedit: SourceEdit;\n\telement: JSXElement;\n\tinput: string;\n}) => {\n\tif (!element.loc) {\n\t\tthrow new Error('Could not locate the video element');\n\t}\n\n\tconst start = recastLocToOffset(input, element.loc.start);\n\tconst end = recastLocToOffset(input, element.loc.end);\n\tif (edit.start < start || edit.end > end) {\n\t\tthrow new Error('Muted attribute edit is outside the video element');\n\t}\n\n\tconst source =\n\t\tinput.slice(start, edit.start) +\n\t\tedit.replacement +\n\t\tinput.slice(edit.end, end);\n\tconst originalIndent = getLineIndent({input, offset: start});\n\treturn source\n\t\t.split(/\\r?\\n/)\n\t\t.map((line, index) => {\n\t\t\tif (index === 0) {\n\t\t\t\treturn line;","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/studio-codemods/src/split-video-from-audio.ts#L224-L260","documentation":"This error is thrown by applyEditToElementSource in the split-video-from-audio codemod when the JSXElement representing the video has no source location (element.loc is null). Without loc offsets the codemod cannot slice the original source around the element, so it refuses to apply the muted-attribute edit. It indicates the AST node was constructed or transformed without position info rather than a problem with the user's code.","triggerScenarios":"splitVideoFromAudio is called and the located <Video>/<OffthreadVideo> JSXElement has loc === null — typically because the element was built programmatically via AST builders, an intermediate recast transform stripped positions, or a synthetic node was passed in instead of one parsed from source.","commonSituations":"Custom callers piping hand-built AST nodes into the codemod internals, running the codemod on code that passed through another transform that dropped source positions, or bugs in codemod preprocessing (e.g. after capturing node paths from a re-created AST).","solutions":["Verify the element passed to applyEditToElementSource comes directly from parseAst(input) so it retains loc information","Re-run the codemod on the original, untransformed source string","If building AST nodes, set their loc fields or round-trip through parse/print so positions are re-derived","Report a Remotion Studio bug if a normal split-video-from-audio action hits this in the UI"],"exampleFix":"// before (synthetic node without loc)\nconst el = b.jsxElement(b.jsxOpeningElement(b.jsxIdentifier('Video'), []), null, []);\napplyEditToElementSource({edit, element: el, input});\n// after (parse from source so loc is present)\nconst ast = parseAst(input);\nconst el = findJsxElementPathForDeletion(ast, nodePath).node;\napplyEditToElementSource({edit, element: el, input});","handlingStrategy":"type-guard","validationCode":"const hasLoc = (el: {loc: unknown}): el is {loc: NonNullable<JSXElement['loc']>} => el.loc != null;\nif (!hasLoc(element)) throw new Error('element has no source location; reparse input');","typeGuard":"const hasLoc = (el: JSXElement): el is JSXElement & {loc: NonNullable<JSXElement['loc']>} => el.loc != null;","tryCatchPattern":"try {\n  const source = applyEditToElementSource({edit, element, input});\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Could not locate')) {\n    const ast = parseAst(input); // reparse and re-resolve the element with loc\n    return applyEditToElementSource({edit, element: findElement(ast), input});\n  }\n  throw e;\n}","preventionTips":["Always resolve AST nodes from parseAst(input), never from builder-built synthetic nodes","Avoid mutating the AST between parsing and edit application","Round-trip programmatically generated code through print+parse to restore loc"],"tags":["ast","codemod","source-location"],"backgroundTag":"missing-source-location","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"}