{"record":{"id":"6583fa8ca3dbac5d","repo":"remotion-dev/remotion","slug":"function-source-edits-only-support-prepended-statements","errorCode":null,"errorMessage":"Function source edits only support prepended statements unless the block body is explicitly reprinted","messagePattern":"Function source edits only support prepended statements unless the block body is explicitly reprinted","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/studio-codemods/src/function-source-edits.ts","lineNumber":300,"sourceCode":"\t\t}\n\n\t\tconst originalStatements = new Set(statements);\n\t\tconst insertedStatements = originalBody.body.filter(\n\t\t\t(statement) => !originalStatements.has(statement),\n\t\t);\n\t\tconst unchangedStatements = originalBody.body.slice(\n\t\t\tinsertedStatements.length,\n\t\t);\n\t\tconst onlyPrependedStatementsChanged =\n\t\t\toriginalBody.body\n\t\t\t\t.slice(0, insertedStatements.length)\n\t\t\t\t.every((statement) => !originalStatements.has(statement)) &&\n\t\t\tunchangedStatements.length === statements.length &&\n\t\t\tunchangedStatements.every(\n\t\t\t\t(statement, index) => statement === statements[index],\n\t\t\t);\n\t\tif (!onlyPrependedStatementsChanged) {\n\t\t\tthrow new Error(\n\t\t\t\t'Function source edits only support prepended statements unless the block body is explicitly reprinted',\n\t\t\t);\n\t\t}\n\n\t\tif (insertedStatements.length === 0 || !originalBody.loc) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst blockStart = recastLocToOffset(input, originalBody.loc.start);\n\t\tconst blockEnd = recastLocToOffset(input, originalBody.loc.end);\n\t\tconst openingBrace = input.indexOf('{', blockStart);\n\t\tif (openingBrace === -1 || openingBrace >= blockEnd) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst firstOriginalStatement = statements[0];\n\t\tconst firstOriginalOffset = firstOriginalStatement?.loc\n\t\t\t? recastLocToOffset(input, firstOriginalStatement.loc.start)","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/studio-codemods/src/function-source-edits.ts#L282-L318","documentation":"getFunctionSourceEditsForPrependedStatements only supports inserting new statements at the very beginning of a function block, leaving all existing statements untouched (verified by comparing original vs current statement lists). If any non-prepended change is detected — statements removed, reordered, or modified — the codemod cannot safely produce edits and throws.","triggerScenarios":"Calling getFunctionSourceEditsForPrependedStatements with an updated function body where existing statements were changed, removed, or reordered rather than only new statements being added at the top of the block.","commonSituations":"Applying a codemod to a file the user edited since the original snapshot; rebased/merged code that altered the function body; a transformation pipeline that rewrites the whole body instead of only prepending.","solutions":["Only add new statements at the start of the function block; keep all original statements byte-identical and in order.","If the body must be restructured, use a codemod/API that explicitly reprints the block body instead of the prepend-only variant.","Re-apply the codemod from the original source state, then apply manual edits afterwards.","Diff the function body against the pre-codemod version to find which existing statement changed."],"exampleFix":"// before (reorders existing statement) -> throws\nbody = [callHook(), ...originalStatements.slice().reverse()];\n// after (only prepend)\nbody = [callHook(), ...originalStatements];","handlingStrategy":"validation","validationCode":"const prependsOnly = newStatements.every((s, i) =>\n  i === 0 || originalStatements[i - 1] === s);\nif (!prependsOnly) throw new Error('Body modified beyond prepending; use a full-reprint codemod');","typeGuard":null,"tryCatchPattern":"try {\n  getFunctionSourceEditsForPrependedStatements(args);\n} catch (e) {\n  if (typeof e.message === 'string' && e.message.includes('only support prepended statements')) {\n    // fall back to a codemod that reprints the block body\n    applyReprintingCodemod(args);\n  } else throw e;\n}","preventionTips":["Never mutate or reorder existing statements when building prepend-only edits","Diff function bodies against the snapshot the codemod was derived from","Apply manual edits after, not before, running prepend codemods"],"tags":["codemod","ast","unsupported-edit"],"backgroundTag":"unsupported-operation","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"}