remotion-dev/remotion · error · Error
Function source edits only support prepended statements…
Error message
Function source edits only support prepended statements unless the block body is explicitly reprinted
What it means
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.
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.
Example fix
// before (reorders existing statement) -> throws body = [callHook(), ...originalStatements.slice().reverse()]; // after (only prepend) body = [callHook(), ...originalStatements];
Defensive patterns
Strategy: validation
Validate before calling
const prependsOnly = newStatements.every((s, i) =>
i === 0 || originalStatements[i - 1] === s);
if (!prependsOnly) throw new Error('Body modified beyond prepending; use a full-reprint codemod'); Try / catch
try {
getFunctionSourceEditsForPrependedStatements(args);
} catch (e) {
if (typeof e.message === 'string' && e.message.includes('only support prepended statements')) {
// fall back to a codemod that reprints the block body
applyReprintingCodemod(args);
} else throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot duplicate JSX element with no parent
- Cannot split a JSX sequence without a source location
- Cannot split audio from a JSX element with no parent
- Cannot split JSX sequence with no parent
- Cannot update keyframes without a JSX source location
AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18).
Data as JSON: /api/errors/6583fa8ca3dbac5d.
Report an issue: GitHub.
Appendix: source
Thrown at packages/studio-codemods/src/function-source-edits.ts:300
}
const originalStatements = new Set(statements);
const insertedStatements = originalBody.body.filter(
(statement) => !originalStatements.has(statement),
);
const unchangedStatements = originalBody.body.slice(
insertedStatements.length,
);
const onlyPrependedStatementsChanged =
originalBody.body
.slice(0, insertedStatements.length)
.every((statement) => !originalStatements.has(statement)) &&
unchangedStatements.length === statements.length &&
unchangedStatements.every(
(statement, index) => statement === statements[index],
);
if (!onlyPrependedStatementsChanged) {
throw new Error(
'Function source edits only support prepended statements unless the block body is explicitly reprinted',
);
}
if (insertedStatements.length === 0 || !originalBody.loc) {
continue;
}
const blockStart = recastLocToOffset(input, originalBody.loc.start);
const blockEnd = recastLocToOffset(input, originalBody.loc.end);
const openingBrace = input.indexOf('{', blockStart);
if (openingBrace === -1 || openingBrace >= blockEnd) {
continue;
}
const firstOriginalStatement = statements[0];
const firstOriginalOffset = firstOriginalStatement?.loc
? recastLocToOffset(input, firstOriginalStatement.loc.start)View on GitHub (pinned to 46a3a6bf13)