Hmbown/CodeWhale · warning · ExecError
cursor position needs an X11 session in this build
Error message
cursor position needs an X11 session in this build
What it means
cursor_position is only implemented for X11 in this backend build. On Wayland sessions the handler falls through to a throw saying an X11 session is required. This is a deliberate fail-closed limit, since Wayland intentionally blocks global pointer-position queries from clients.
Solutions
- Log in with an 'Xorg' session (GNOME on Xorg, Plasma X11) if cursor position is required
- Read the cursor via a Wayland-native route, e.g. an overlay/compositor extension or `dotool`/compositor-specific IPC
- Skip cursor-position features on Wayland and use screenshot+coordinate workflows instead
Example fix
// before const pos = await backend.cursor_position(); // after const session = await detectSession(); const pos = session === 'x11' ? await backend.cursor_position() : null; // unsupported on Wayland
Defensive patterns
Strategy: validation
Validate before calling
if (sessionType !== 'x11') throw new SkipError('cursor_position requires X11; session is ' + sessionType); Type guard
const supportsCursorPosition = (backend) => backend.session === 'x11';
Prevention
- Detect the session type (X11 vs Wayland) before advertising cursor features
- Gate cursor-position capabilities in capability discovery
- Prefer Xorg sessions in automation environments
When it happens
Trigger: Calling cursor_position while probeSession detected a Wayland session (wl-* tooling) rather than X11.
Common situations: GNOME/KDE Wayland desktops (the default on modern distros); apps forced onto Wayland via environment variables; hybrid setups where the app sees XWayland but the session reported Wayland.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- clipboard read failed
- linux backend needs " " for — install it and retry
- PRIMARY selection busy or unavailable
- scroll on Wayland is not available in this build; use…
- could not parse xdotool getmouselocation output
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/2c833dcb94719d36.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/src/backends/linux.mjs:768
},
write_clipboard: async ({ text }) => {
await probeSession();
const cmd = session === "x11"
? (tools.xclip ? ["xclip", "-selection", "clipboard"] : ["xsel", "--clipboard", "--input"])
: ["wl-copy"];
need(cmd[0], "clipboard write");
spawnDetached(cmd[0], cmd.slice(1), String(text ?? ""), true);
return { written: String(text ?? "").length };
},
cursor_position: async () => {
await probeSession();
if (session === "x11") {
const out = await xdotool(["getmouselocation"]);
const m = /x:(-?\d+)\s+y:(-?\d+)/.exec(out);
if (!m) throw new ExecError(`could not parse xdotool getmouselocation output: ${out}`);
return { x: Number(m[1]), y: Number(m[2]) };
}
throw new ExecError("cursor position needs an X11 session in this build");
},
recordingStart: async () => {
throw Object.assign(new ExecError("Recording is unavailable on this platform until the recorder has session-owned cleanup. Use screenshots instead."), { code: "owned_recording_unavailable" });
},
recordingStop: async ({ id }) => { throw new ExecError(`unknown recording "${id}"`); },
recordingStatus: ({ id }) => ({ id, running: false }),
recordingList: async () => {
const dir = recordingsDir();
const out = fs.existsSync(dir)
? fs.readdirSync(dir).filter((f) => /\.(mp4|mkv|png)$/i.test(f)).map((f) => {
const st = fs.statSync(path.join(dir, f));
return { file: path.join(dir, f), bytes: st.size, modifiedAt: st.mtime.toISOString() };
}).sort((a, b) => b.modifiedAt.localeCompare(a.modifiedAt)).slice(0, 50)
: [];
return { dir, recordings: out, running: [] };
},
};
View on GitHub (pinned to 73e0f67d83)