remotion-dev/remotion · error
Cannot reorder effect: source index not-found
Error message
Cannot reorder effect: source index not-found
What it means
reorderEffect validates fromIndex against the enumerated effects array (enumerateEffectArrayElements) before moving. An index below zero or at/above the number of elements means the source effect to move does not exist, so it throws. A companion check validates toIndex ('target index not-found').
Solutions
- Clamp/recompute fromIndex against the current array length before calling
- Re-enumerate effects on the current source and refresh both indices
- Guard: if (fromIndex >= 0 && fromIndex < elements.length) before invoking
Example fix
// before
reorderEffect({fromIndex: 5, toIndex: 0, ...}); // 2 effects exist
// after
const i = Math.min(fromIndex, elements.length - 1); reorderEffect({fromIndex: i, toIndex: 0, ...}); Defensive patterns
Strategy: validation
Validate before calling
const elements = enumerateEffectArrayElements(getEffectsArray(findEffectsAttr(jsx.openingElement.attributes)!, 'check'));
if (fromIndex < 0 || fromIndex >= elements.length) throw new Error('fromIndex out of range');
if (toIndex < 0 || toIndex >= elements.length) throw new Error('toIndex out of range'); Type guard
const inBounds = (i: number, len: number): i is number => Number.isInteger(i) && i >= 0 && i < len;
Try / catch
try { await reorderEffect({fromIndex, toIndex, input, sequenceNodePath}); } catch (e) { if ((e as Error).message.includes('source index not-found')) { /* refresh indices from current source and retry once */ } else throw e; } Prevention
- Recompute indices immediately before reordering — never cache across edits
- Clamp UI drag targets to the current array length
- Delete and reorder flows should share one fresh enumeration source
When it happens
Trigger: reorderEffect with fromIndex < 0 or fromIndex >= effects.length — typically an effect index captured before effects were deleted, or an index counted on a different element.
Common situations: Drag-and-drop reorder in Studio after another effect was deleted making stored indices stale; hard-coded index in an automation script; array shrank because non-call entries were cleaned up.
Related errors
- Cannot duplicate effect
- "colors" must be an array with at least 2 colors, but got
- "colors" must be an array with at least 2 colors, but got
- "colors" must be an array with at least 2 colors, but got
- "fieldOfView" must be <=
AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18).
Data as JSON: /api/errors/c07644c0ce56f2da.
Report an issue: GitHub.
Appendix: source
Thrown at packages/studio-codemods/src/effect-operations.ts:596
} & EffectSourceStyleOptions): Promise<{
output: string;
formatted: boolean;
effectLabel: string;
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);
}View on GitHub (pinned to 46a3a6bf13)