remotion-dev/remotion · warning
Cannot paste effects: no effects were copied
Error message
Cannot paste effects: no effects were copied
What it means
In non-replacing paste modes (additive), if the clipboard produced zero effect calls the library cannot paste anything and throws this error. Only 'effects-replacing' may legitimately result in zero effects (it just removes the existing effects attribute).
Solutions
- Check the copied effects list is non-empty before enabling or invoking paste.
- Fix the copy step so it actually captures effect entries from the source element.
- If a paste with zero effects should be a silent no-op in your UI, guard the call.
Example fix
// before
await pasteEffects({input, targetSequenceNodePath, effects: clipboard.effects, type: 'effects-additive', insertAtIndices: null});
// after
if (clipboard.effects.length > 0) {
await pasteEffects({input, targetSequenceNodePath, effects: clipboard.effects, type: 'effects-additive', insertAtIndices: null});
} Defensive patterns
Strategy: validation
Validate before calling
if (type !== 'effects-replacing' && clipboardEffects.length === 0) {
return; // nothing to paste
} Type guard
const hasCopiedEffects = ( effects: EffectClipboardEntry[], ): effects is [EffectClipboardEntry, ...EffectClipboardEntry[]] => effects.length > 0;
Try / catch
try {
await pasteEffects(args);
} catch (e) {
if (e instanceof Error && e.message === 'Cannot paste effects: no effects were copied') {
// surface 'clipboard empty' to the user
} else throw e;
} Prevention
- Verify the copy step actually captured effect entries.
- Disable paste UI while the clipboard effect list is empty.
When it happens
Trigger: Calling pasteEffects with type 'effects-additive' (or null insertAtIndices additive mode) and an empty effects array — e.g. the clipboard/copy step captured nothing, or all copied effects were filtered out before the paste call.
Common situations: Copy action that silently failed or copied an element with an empty effects array; clipboard state reset but paste invoked; an app bug clearing the copied effects list between copy and paste.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Image has not loaded
- No effects were specified for deletion
- A skill is already being installed or removed. Please try…
- Asset was not found in public/.
- assetPath must be a non-empty public-folder path, or an…
AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18).
Data as JSON: /api/errors/f832b7a8a60d4608.
Report an issue: GitHub.
Appendix: source
Thrown at packages/studio-codemods/src/effect-operations.ts:895
insertAtIndices.length !== calls.length ||
new Set(insertAtIndices).size !== insertAtIndices.length ||
insertAtIndices.some((index) => !Number.isInteger(index) || index < 0))
) {
throw new Error('Cannot paste effects: invalid insertion indices');
}
if (type === 'effects-replacing') {
if (existingAttr) {
jsx.attributes.splice(jsx.attributes.indexOf(existingAttr), 1);
}
if (calls.length > 0) {
jsx.attributes.push(
makeEffectsAttr(b.arrayExpression(calls as never) as ArrayExpression),
);
}
} else if (calls.length === 0) {
throw new Error('Cannot paste effects: no effects were copied');
} else if (insertAtIndices === null) {
if (existingAttr) {
getEffectsArray(existingAttr, 'paste').elements.push(
...(calls as ArrayExpression['elements']),
);
} else {
jsx.attributes.push(
makeEffectsAttr(b.arrayExpression(calls as never) as ArrayExpression),
);
}
} else {
const elements = existingAttr
? getEffectsArray(existingAttr, 'paste').elements
: ([] as ArrayExpression['elements']);
for (const item of calls
.map((effect, index) => ({effect, index: insertAtIndices[index]!}))
.sort((a, bValue) => a.index - bValue.index)) {
elements.splice(Math.min(item.index, elements.length), 0, item.effect);View on GitHub (pinned to 46a3a6bf13)