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
- Verify the value passed to `action` is exactly the lowercase string 'copy' or 'cut' (case-sensitive).
- 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()`.
- If the intent is to let the default apply, omit the `action` option entirely instead of passing `undefined`/`null`.
- 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
- Treat action as an enum, never a free-form string — derive it from a single constant map.
- When action comes from a data attribute or URL param, whitelist it before forwarding.
- Add a unit test asserting the action function can only ever return 'copy' or 'cut'.
- Avoid uppercase variants in the data layer; normalize at the boundary.
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
- Invalid "target" value, use a valid Element
- Invalid "target" attribute. Please use "readonly" instead of
- Invalid "target" attribute. You can't cut text from elements
AI-assisted analysis of zenorocha/clipboard.js@899378dee9 (2026-08-13).
Data as JSON: /api/errors/9a3e5d0c2b0e4295.
Report an issue: GitHub.