{"record":{"id":"a76380ba14742c1a","repo":"zenorocha/clipboard.js","slug":"invalid-target-attribute-you-can-t-cut-text-fro","errorCode":null,"errorMessage":"Invalid \"target\" attribute. You can't cut text from elements with \"readonly\" or \"disabled\" attributes","messagePattern":"Invalid \"target\" attribute\\. You can't cut text from elements with \"readonly\" or \"disabled\" attributes","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/actions/default.js","lineNumber":31,"sourceCode":"  // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n  if (action !== 'copy' && action !== 'cut') {\n    throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n  }\n\n  // Sets the `target` property using an element that will be have its content copied.\n  if (target !== undefined) {\n    if (target && typeof target === 'object' && target.nodeType === 1) {\n      if (action === 'copy' && target.hasAttribute('disabled')) {\n        throw new Error(\n          'Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute'\n        );\n      }\n\n      if (\n        action === 'cut' &&\n        (target.hasAttribute('readonly') || target.hasAttribute('disabled'))\n      ) {\n        throw new Error(\n          'Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes'\n        );\n      }\n    } else {\n      throw new Error('Invalid \"target\" value, use a valid Element');\n    }\n  }\n\n  // Define selection strategy based on `text` property.\n  if (text) {\n    return ClipboardActionCopy(text, { container });\n  }\n\n  // Defines which selection strategy based on `target` property.\n  if (target) {\n    return action === 'cut'\n      ? ClipboardActionCut(target)\n      : ClipboardActionCopy(target, { container });","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/zenorocha/clipboard.js/blob/899378dee9681dcf4cb3d702c23a3f3cd9f473d8/src/actions/default.js#L13-L49","documentation":"Thrown when `action` is 'cut' and the target element has either a `readonly` or `disabled` attribute. Cut both selects AND clears the source value, which requires the field to be user-editable; a readonly/disabled field cannot be modified, so the cut cannot be completed and the library aborts before partial state.","triggerScenarios":"Setting `data-clipboard-action=\"cut\"` on a trigger whose `data-clipboard-target` points at `<input readonly>` or `<input disabled>`; calling `ClipboardActionDefault({ action: 'cut', target: el })` where `el` is a readonly textarea; a dynamic `action: () => 'cut'` applied to a field that is readonly in some states but not others.","commonSituations":"Move-to-clipboard UX (cut) on inputs that are conditionally readonly (locked records, review-mode forms); admin tools where fields flip to readonly after approval but cut buttons remain bound; mixing copy and cut triggers on the same field without coordinating its editable state; SSR templates that render fields as readonly by default.","solutions":["Confirm the field is actually meant to be emptied — if not, switch the trigger's action to 'copy' instead of 'cut'.","Remove the `readonly`/`disabled` attribute from the target before the cut runs (in a click handler or before calling ClipboardActionDefault).","Rework the UX so cut is only enabled when the field is editable — disable the cut button itself when the target is readonly/disabled.","Use the `text` callback path with manual clearing afterwards if you must read from a readonly field (note: you still cannot auto-clear it via this library)."],"exampleFix":"// before\n<input id=\"note\" value=\"scratch\" readonly />\n<button data-clipboard-action=\"cut\" data-clipboard-target=\"#note\">Cut</button>\n// after\n<input id=\"note\" value=\"scratch\" />\n<button data-clipboard-action=\"cut\" data-clipboard-target=\"#note\">Cut</button>","handlingStrategy":"validation","validationCode":"function canCutFrom(el) {\n  if (!el || el.nodeType !== 1) return false;\n  return !el.hasAttribute('readonly') && !el.hasAttribute('disabled');\n}\nconst el = document.querySelector('#note');\nif (!canCutFrom(el)) {\n  cutBtn.disabled = true; // don't attempt a doomed cut\n} else {\n  cutBtn.disabled = false;\n}","typeGuard":"/**\n * @param {Element} el\n * @returns {boolean}\n */\nfunction isCuttableElement(el) {\n  if (!(el instanceof Element) || el.nodeType !== 1) return false;\n  return !el.hasAttribute('readonly') && !el.hasAttribute('disabled');\n}","tryCatchPattern":"try {\n  ClipboardActionDefault({ action: 'cut', target: el });\n} catch (err) {\n  if (/can't cut text from elements/.test(err.message)) {\n    console.warn('Target is not editable; falling back to copy', el);\n    ClipboardActionDefault({ action: 'copy', target: el });\n  } else {\n    throw err;\n  }\n}","preventionTips":["Tie the cut button's `disabled` state to the target's readonly/disabled state so an invalid cut can never be attempted.","Confirm with the product whether the field is truly meant to be cleared — most readonly fields should be copied, not cut.","Run a guard check on focus/click before invoking the clipboard action.","When field state flips (e.g., lock-after-save), re-evaluate bound actions rather than leaving stale bindings."],"tags":["clipboard","dom","form-controls","attribute-mismatch","state-mutation"],"backgroundTag":null,"analyzedSha":"899378dee9681dcf4cb3d702c23a3f3cd9f473d8","analyzedAt":"2026-08-13T04:33:09.334Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}