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
- Clamp toIndex into [0, elements.length - 1] before calling reorderEffect.
- Re-read the current effect list from the source file to refresh indices before reordering.
- For moving to the end, pass elements.length - 1, not elements.length.
- 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
- Always derive indices from a freshly parsed effect list, never a cached UI model.
- Clamp drop indices to elements.length - 1 in drag-and-drop handlers.
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
- Cannot update effect prop
- Cannot delete effect: no effects found
- Cannot reorder effect: source effect is not-call-expression
- Could not find as a reorder target
- A skill is already being installed or removed. Please try…
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)