remotion-dev/remotion · error

Cannot reorder effect: target index not-found

Error message

Cannot reorder effect: target index not-found

What it means

reorderEffect() moves the effect at fromIndex to toIndex inside the target element's effects={[]} array. After enumerating the array elements, it validates that toIndex points at an existing slot; if toIndex is negative or >= the number of elements, it throws this error before mutating the AST. The array is not modified when this throws.

Solutions

  1. Clamp toIndex into [0, elements.length - 1] before calling reorderEffect.
  2. Re-read the current effect list from the source file to refresh indices before reordering.
  3. For moving to the end, pass elements.length - 1, not elements.length.
  4. Verify you resolved the correct sequenceNodePath so you are counting the effects array you actually intend to reorder.

Example fix

// before
await reorderEffect({input, fromIndex: 1, toIndex: 5, sequenceNodePath});
// after
const count = getEffectCount(input, sequenceNodePath); // e.g. 3
await reorderEffect({input, fromIndex: 1, toIndex: Math.min(5, count - 1), sequenceNodePath});
Defensive patterns

Strategy: validation

Validate before calling

const count = enumerateEffects(input, sequenceNodePath).length;
if (!Number.isInteger(toIndex) || toIndex < 0 || toIndex >= count) {
  throw new RangeError(`toIndex ${toIndex} out of range (0..${count - 1})`);
}

Type guard

const isValidIndex = (i: number, length: number): i is number =>
  Number.isInteger(i) && i >= 0 && i < length;

Try / catch

try {
  await reorderEffect({input, fromIndex, toIndex, sequenceNodePath});
} catch (e) {
  if (e instanceof Error && e.message.includes('target index not-found')) {
    // refresh effect list / clamp index and retry once
  } else throw e;
}

Prevention

When it happens

Trigger: Calling reorderEffect({fromIndex, toIndex, input, sequenceNodePath}) where toIndex < 0 or toIndex >= elements.length — e.g. toIndex equal to the array length (off-by-one when appending), or toIndex computed from a stale UI list after effects were added/removed in the source file.

Common situations: Studio drag-and-drop reorder where the drop index was captured against a cached effect list; source edited manually (an effect removed) so the target index no longer exists; passing toIndex = elements.length intending 'move to end'.

Related errors


AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18). Data as JSON: /api/errors/1b5b71fb53abf717. Report an issue: GitHub.

Appendix: source

Thrown at packages/studio-codemods/src/effect-operations.ts:600

	logLine: number;
}> =>
	Promise.resolve().then(() => {
		const ast = parseAst(input);
		const snapshots = captureEffectSourceSnapshots(ast);
		const jsx = getJsx({action: 'reorder', ast, sequenceNodePath});
		const attr = findEffectsAttr(jsx.attributes);
		if (!attr) {
			throw new Error('Could not find effects on the target JSX element');
		}

		const array = getEffectsArray(attr, 'reorder');
		const elements = enumerateEffectArrayElements(array);
		if (fromIndex < 0 || fromIndex >= elements.length) {
			throw new Error('Cannot reorder effect: source index not-found');
		}

		if (toIndex < 0 || toIndex >= elements.length) {
			throw new Error('Cannot reorder effect: target index not-found');
		}

		const target = elements[fromIndex];
		if (target.kind !== 'call') {
			throw new Error(
				'Cannot reorder effect: source effect is not-call-expression',
			);
		}

		trackOpeningElement({jsx, snapshots});
		if (fromIndex !== toIndex) {
			const [moved] = array.elements.splice(fromIndex, 1);
			array.elements.splice(toIndex, 0, moved as never);
		}

		return {
			output: getEffectSourceOutput({
				ast,

View on GitHub (pinned to 46a3a6bf13)