{"record":{"id":"473a9d6bf8d89bd5","repo":"remotion-dev/remotion","slug":"could-not-locate-the-folder-to-delete","errorCode":null,"errorMessage":"Could not locate the folder to delete","messagePattern":"Could not locate the folder to delete","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/studio-codemods/src/folder-source-edits.ts","lineNumber":281,"sourceCode":"\n\treturn lines\n\t\t.map((line) => (line.trim() === '' ? '' : line.slice(commonIndent.length)))\n\t\t.join(getEndOfLine(source));\n};\n\nconst isMeaningfulChild = (child: JSXElement['children'][number]) =>\n\tchild.type !== 'JSXText' || child.value.trim() !== '';\n\nconst getDeleteFolderSourceEdit = ({\n\tinput,\n\tlocated,\n}: {\n\tinput: string;\n\tlocated: LocatedItem;\n}): SourceEdit => {\n\tconst {node, path} = located;\n\tif (!node.loc) {\n\t\tthrow new Error('Could not locate the folder to delete');\n\t}\n\n\tconst openingEnd = node.openingElement.loc\n\t\t? recastLocToOffset(input, node.openingElement.loc.end)\n\t\t: null;\n\tconst closingStart = node.closingElement?.loc\n\t\t? recastLocToOffset(input, node.closingElement.loc.start)\n\t\t: null;\n\tconst inner =\n\t\topeningEnd === null || closingStart === null\n\t\t\t? ''\n\t\t\t: normalizeBlock(input.slice(openingEnd, closingStart));\n\n\tif (!located.directJsxChild) {\n\t\tconst meaningfulChildren = node.children.filter(isMeaningfulChild);\n\t\tif (meaningfulChildren.length === 0) {\n\t\t\treturn {\n\t\t\t\tstart: recastLocToOffset(input, node.loc.start),","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/studio-codemods/src/folder-source-edits.ts#L263-L299","documentation":"Thrown by getDeleteFolderSourceEdit (folder-source-edits.ts:281) when the located folder's JSXElement has no source location (`node.loc` is null). Deleting a folder requires computing character offsets from the node's loc; a location-less node (typically one synthesized by an earlier AST mutation in the same codemod run) cannot be mapped back to text.","triggerScenarios":"A `delete-folder` codemod targets a folder whose JSXElement node lost its recast `loc`, usually because the node was created or replaced programmatically during applyCodemod rather than existing in the original parsed source.","commonSituations":"Deleting a folder right after another codemod moved/created nodes in the same file within one Studio session, or Root files where the folder JSX was generated rather than hand-written.","solutions":["Reload the Studio / re-parse the file so all JSX nodes regain source locations, then delete again","Delete the <Folder> element manually in the editor","Avoid chaining create+delete folder operations on the same unsaved file"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Re-parse the file first so nodes carry fresh locations\nconst ast = parseAst(input);\nif (getLocatedItems(ast).every((i) => !i.node.loc)) {\n  throw new Error('File nodes lack source locations; save/reformat first');\n}","typeGuard":"const isLocatable = (node: JSXElement): node is JSXElement & {loc: NonNullable<JSXElement['loc']>} => node.loc !== null && node.loc !== undefined;","tryCatchPattern":"try {\n  editFolderInSource({codeMod, input});\n} catch (e) {\n  if (e instanceof Error && e.message === 'Could not locate the folder to delete') {\n    // delete the <Folder> block manually\n  }\n}","preventionTips":["Reload/re-parse the file before chained create+delete operations","Avoid deleting folders whose JSX was just synthesized in the same run","Keep Root files hand-written so recast locations stay intact"],"tags":["ast","codemod","delete","jsx"],"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"}