zenorocha/clipboard.js · error · Error

Invalid "action" value, use either "copy" or "cut"

Error message

Invalid "action" value, use either "copy" or "cut"

What it means

Thrown by ClipboardActionDefault when the `action` option is set to any value other than 'copy' or 'cut'. The option defaults to 'copy' when omitted, so the error only fires when an explicit invalid string is passed. The library enforces this because only copy and cut have corresponding selection/execution strategies wired up.

Source

Thrown at src/actions/default.js:15

import ClipboardActionCut from './cut';
import ClipboardActionCopy from './copy';

/**
 * Inner function which performs selection from either `text` or `target`
 * properties and then executes copy or cut operations.
 * @param {Object} options
 */
const ClipboardActionDefault = (options = {}) => {
  // Defines base properties passed from constructor.
  const { action = 'copy', container, target, text } = options;

  // Sets the `action` to be performed which can be either 'copy' or 'cut'.
  if (action !== 'copy' && action !== 'cut') {
    throw new Error('Invalid "action" value, use either "copy" or "cut"');
  }

  // Sets the `target` property using an element that will be have its content copied.
  if (target !== undefined) {
    if (target && typeof target === 'object' && target.nodeType === 1) {
      if (action === 'copy' && target.hasAttribute('disabled')) {
        throw new Error(
          'Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'
        );
      }

      if (
        action === 'cut' &&
        (target.hasAttribute('readonly') || target.hasAttribute('disabled'))
      ) {
        throw new Error(
          'Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'
        );

View on GitHub (pinned to 899378dee9)

Solutions

  1. Verify the value passed to `action` is exactly the lowercase string 'copy' or 'cut' (case-sensitive).
  2. If `action` is computed by a function (e.g., `action: () => someState`), log/inspect that function's return value at runtime and coerce it with `.toLowerCase()`.
  3. If the intent is to let the default apply, omit the `action` option entirely instead of passing `undefined`/`null`.
  4. Where the action originates from user/config input, whitelist it before forwarding: `const a = ['copy','cut'].includes(input) ? input : 'copy';`.

Example fix

// before
new ClipboardJS(btn, { action: () => targetEl.getAttribute('data-act') });
// after
new ClipboardJS(btn, {
  action: () => {
    const act = targetEl.getAttribute('data-act');
    return act === 'cut' ? 'cut' : 'copy'; // coerce to a known value
  }
});
Defensive patterns

Strategy: validation

Validate before calling

const VALID_ACTIONS = new Set(['copy', 'cut']);
function resolveAction(raw) {
  if (raw === undefined || raw === null) return 'copy'; // let default apply
  const a = String(raw).toLowerCase();
  if (!VALID_ACTIONS.has(a)) {
    throw new Error(`Unsupported clipboard action: ${JSON.stringify(raw)}`);
  }
  return a;
}
// usage
new ClipboardJS(btn, { action: () => resolveAction(getUserAction()) });

Type guard

// narrow a dynamic value to the allowed action union
/**
 * @param {unknown} v
 * @returns {v is 'copy'|'cut'}
 */
function isClipboardAction(v) {
  return v === 'copy' || v === 'cut';
}

Try / catch

try {
  ClipboardActionDefault({ action: maybeAction, target: el });
} catch (err) {
  if (/Invalid "action" value/.test(err.message)) {
    console.warn('Clipboard action ignored; falling back to copy', maybeAction);
    ClipboardActionDefault({ action: 'copy', target: el });
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Passing `new ClipboardJS(el, { action: () => 'paste' })` whose action function returns a value other than 'copy'/'cut'; calling `ClipboardActionDefault({ action: 'paste' })` directly; passing a typo like 'Copy' (capital C) or 'cunt'/'cit'; passing a non-string such as `action: undefined` won't trigger it (default kicks in) but `action: null` will since `null !== 'copy'`.

Common situations: Dynamic `action` functions whose return value comes from a data attribute, dropdown, or external config that yields an unexpected string; case mismatch ('Copy' vs 'copy'); i18n pipelines that translate the literal action word; refactors that change the action source without updating the consumer; passing a bitwise/numeric action code.

Related errors


AI-assisted analysis of zenorocha/clipboard.js@899378dee9 (2026-08-13). Data as JSON: /api/errors/9a3e5d0c2b0e4295. Report an issue: GitHub.