remotion-dev/remotion · error
Cannot reorder effect: source effect is not-call-expression
Error message
Cannot reorder effect: source effect is not-call-expression
What it means
reorderEffect() only supports moving entries of the effects array that are plain call expressions like <FadeIn/> style effects={[(interpolate(...), Spring())]}. If the element at fromIndex is a spread element, hole, or any other non-call node, it throws this error. The reorder operation cannot represent such entries safely when moving them.
Solutions
- Choose a fromIndex that points at an actual effect call (e.g. the Spring() or interpolate() entry).
- Rewrite the source so spread elements are flattened into explicit calls before reordering.
- Check enumerateEffectArrayElements output/kind in your tooling to skip non-call entries in the UI.
Example fix
// before
<Sequence effects={[...extraEffects, Spring()]} /> // reorderEffect fromIndex: 0 hits the spread
// after
<Sequence effects={[FadeIn(), Spring()]} /> // reorderEffect fromIndex: 0 hits FadeIn() Defensive patterns
Strategy: type-guard
Validate before calling
const elements = enumerateEffectArrayElements(getEffectsArray(attr));
if (elements[fromIndex].kind !== 'call') {
throw new TypeError('Source effect is not a call expression');
} Type guard
const isCallElement = (
el: EffectArrayElement,
): el is Extract<EffectArrayElement, {kind: 'call'}> => el.kind === 'call'; Try / catch
try {
await reorderEffect({input, fromIndex, toIndex, sequenceNodePath});
} catch (e) {
if (e instanceof Error && e.message.includes('not-call-expression')) {
// disable reorder UI for this row or flatten spreads first
} else throw e;
} Prevention
- Keep effects arrays literal: flatten spreads and avoid holes.
- Only expose reorder controls for rows whose element kind is 'call'.
When it happens
Trigger: Calling reorderEffect({fromIndex, ...}) where the effects array at that index contains something other than a call expression — e.g. effects={[...(someArray), Spring()]} and fromIndex points at the spread element, or an array hole from sparse literals.
Common situations: Hand-edited JSX where a developer spread an array into effects; generated code that included spreads; sparse arrays; UI showing all indices as draggable including non-call entries.
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 delete effect: no effects found
- Cannot reorder effect: target index not-found
- Cannot update effect prop: computed
- Cannot update effect prop
- Could not find as a reorder target
AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18).
Data as JSON: /api/errors/371d2201fd0a11c0.
Report an issue: GitHub.
Appendix: source
Thrown at packages/studio-codemods/src/effect-operations.ts:605
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,
input,
prettierConfigOverride: prettierConfigOverride ?? null,
snapshots,
}),
formatted: true,View on GitHub (pinned to 46a3a6bf13)