Hmbown/CodeWhale · warning · ExecError

select_text is not implemented on the linux backend —…

Error message

select_text is not implemented on the linux backend — fail-closed

What it means

The linux computer-use backend does not implement select_text; the create path raises this sentinel to fail closed rather than silently performing no selection. Any automation invoking select_text on Linux hits this guard — the unsupported operation itself is the input at fault.

Solutions

  1. Do not call select_text on Linux; check backend capabilities before invoking.
  2. Use perform_action with an appropriate a11y action on the text element, or select via keyboard (key sequences like shift+arrows through the key API).
  3. Gate the call: if (platform !== 'darwin') skip selection step.
  4. If selection is essential, route that step through an X11 clipboard-based workaround (copy via key, then read_clipboard).

Example fix

// before
await backend.select_text({ target, range: [0, 10] }); // always throws on linux
// after
if (backend.capabilities?.includes('select_text')) {
  await backend.select_text({ target, range: [0, 10] });
} else {
  await backend.key({ text: 'Home' });
  await backend.key({ text: 'shift+End' }); // keyboard selection fallback
}
Defensive patterns

Strategy: fallback

Validate before calling

if (!backendCapabilities.includes('select_text')) useKeyboardSelection();

Try / catch

try {
  await backend.select_text(args);
} catch (e) {
  if (String(e.message).includes('not implemented on the linux backend')) {
    return keyboardSelectFallback(args); // key: shift+arrows etc.
  }
  throw e;
}

Prevention

When it happens

Trigger: Any call to backend.select_text(...) regardless of arguments, on the linux backend.

Common situations: Cross-platform scripts written against a macOS/Windows backend that supports select_text, run unmodified against Linux; feature-detection code missing a capability check before invoking selection.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/71218500afe51ec4. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/plugins/computer-use/src/backends/linux.mjs:724

        text = found.queryText()
        after = text.getText(0, text.characterCount)
        if after != extra:
            raise RuntimeError("value_verification_failed")
    else:
        import math
        desired = float(extra)
        if not math.isfinite(desired):
            raise RuntimeError("invalid_value")
        numeric = found.queryValue()
        numeric.currentValue = desired
        after = numeric.currentValue
        if after != desired:
            raise RuntimeError("value_verification_failed")
    print(json.dumps({"ok": True, "after": after}))`, String(value));
      if (!out.ok) throw new ExecError(`set_value failed: ${out.code}`);
      return { action_sent: true, strategy: "a11y", verified: true, after: out.after };
    },
    select_text: async () => { throw new ExecError("select_text is not implemented on the linux backend — fail-closed"); },
    perform_action: async ({ target, action }) => {
      const body = `    a = found.queryAction()
    names = [a.getName(i) for i in range(a.nActions)]
    want = (extra or "click").lower()
    match = next((n for n in names if n.lower() == want), None)
    if match is None and want == "click":
        match = next((n for n in names if n.lower() in ("click", "press", "activate")), None)
    if match is None:
        print(json.dumps({"ok": False, "code": "action_not_found: " + ",".join(names)}))
    else:
        a.doAction(names.index(match))
        print(json.dumps({"ok": True, "sent": True}))`;
      const out = await atspiResolve(target, body, String(action));
      if (!out.ok) throw new ExecError(`perform_action failed: ${out.code}`);
      return { action_sent: true, strategy: "a11y", action };
    },
    read_clipboard: async () => {
      await probeSession();

View on GitHub (pinned to 73e0f67d83)