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

  1. Only add new statements at the start of the function block; keep all original statements byte-identical and in order.
  2. If the body must be restructured, use a codemod/API that explicitly reprints the block body instead of the prepend-only variant.
  3. Re-apply the codemod from the original source state, then apply manual edits afterwards.
  4. 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

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


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)