{"record":{"id":"38da1add92e4629a","repo":"Hmbown/CodeWhale","slug":"element-read-only","errorCode":null,"errorMessage":"element_read_only","messagePattern":"element_read_only","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/backends/linux.mjs","lineNumber":703,"sourceCode":"          await xdotool([\"keydown\", k]);\n          await wait(d * 1000);\n        } finally { await releaseKey(k); }\n      } else await waylandKey(text, { holdMs: Math.round(d * 1000) });\n      return { action_sent: true, key: k, heldSec: d };\n    },\n    set_value: async ({ target, value }) => {\n      // Select a supported interface before sending input. A refused write or\n      // failed readback must never trigger a second, ambiguously applied edit.\n      const out = await atspiResolve(target, `    state = found.getState()\n    if not state.contains(pyatspi.STATE_ENABLED):\n        raise RuntimeError(\"element_disabled\")\n    try:\n        editor = found.queryEditableText()\n    except NotImplementedError:\n        editor = None\n    if editor is not None:\n        if not state.contains(pyatspi.STATE_EDITABLE):\n            raise RuntimeError(\"element_read_only\")\n        if not editor.setTextContents(extra):\n            raise RuntimeError(\"value_rejected\")\n        text = found.queryText()\n        after = text.getText(0, text.characterCount)\n        if after != extra:\n            raise RuntimeError(\"value_verification_failed\")\n    else:\n        import math\n        desired = float(extra)\n        if not math.isfinite(desired):\n            raise RuntimeError(\"invalid_value\")\n        numeric = found.queryValue()\n        numeric.currentValue = desired\n        after = numeric.currentValue\n        if after != desired:\n            raise RuntimeError(\"value_verification_failed\")\n    print(json.dumps({\"ok\": True, \"after\": after}))`, String(value));\n      if (!out.ok) throw new ExecError(`set_value failed: ${out.code}`);","sourceCodeStart":685,"sourceCodeEnd":721,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/backends/linux.mjs#L685-L721","documentation":"set_value on the linux backend writes text via the AT-SPI EditableText interface when the target exposes it. If the element's state lacks STATE_EDITABLE — meaning the interface exists but the control rejects text modification — the script raises RuntimeError(\"element_read_only\") instead of attempting a doomed write.","triggerScenarios":"Calling set_value on a read-only text view, a label, a static document region, or any widget whose AT-SPI state omits STATE_EDITABLE while it still implements queryEditableText-adjacent interfaces.","commonSituations":"Automating a results/log pane that looks like a text field but is read-only; trying to edit a locked form after submission; targeting a password or computed field rendered as non-editable.","solutions":["Target the actual editable input rather than the read-only display element","Remove the read-only condition in the application under automation first","Use clipboard/keyboard strategies (if exposed by the backend) instead of direct text-set","Verify the target selector resolves to the intended widget, not a sibling label"],"exampleFix":"// before\nawait backend.set_value({ target: \"#summary-view\", value: \"hi\" }) // read-only\n// after\nawait backend.set_value({ target: \"#summary-input\", value: \"hi\" });","handlingStrategy":"validation","validationCode":"const state = await backend.get_state?.(target);\nif (state && !state.editable) throw new Error(`target ${target} is read-only`);","typeGuard":"const isEditable = (s) => s?.editable === true;","tryCatchPattern":"try { await backend.set_value({ target, value }); } catch (e) { if (String(e).includes(\"element_read_only\")) { return useKeyboardFallback(target, value); } throw e; }","preventionTips":["Target input widgets, not their read-only labels or display panes","Inspect roles/states during script development to confirm editability","Treat read-only surfaces as output-only; write to their backing controls instead"],"tags":["accessibility","atspi","linux","ui-automation"],"backgroundTag":"element-read-only","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}