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

  1. Check the copied effects list is non-empty before enabling or invoking paste.
  2. Fix the copy step so it actually captures effect entries from the source element.
  3. 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

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


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)