Hmbown/CodeWhale · error · ExecError
shared_pointer_required
shared_pointer_required
Error message
This action needs the shared macOS pointer and was not sent in background mode. Use an accessibility action or a separate computer; foreground control requires exclusive desktop use authorized by the user.
What it means
Some macOS pointer actions (global gestures like drags) need the shared hardware pointer, and requireSharedPointer only permits them when the session runs in background/shared mode (state.foregroundInput set). In foreground mode the backend has been authorized for exclusive desktop use; refusing here prevents the agent from hijacking the user's only pointer without that authorization.
Solutions
- Re-open the session in background/shared mode (set the background_input/foreground option appropriately when calling open_application) so shared-pointer actions are allowed.
- Replace the gesture with an accessibility element action (AXPress etc.) which doesn't need the shared pointer.
- Run the target on a separate computer/virtual display so the shared pointer is genuinely free.
- If foreground control is truly intended, obtain explicit user authorization for exclusive desktop use and start the session in foreground mode.
Example fix
// before
await open_application(app, { foreground: true });
await pointer_sequence({ actions: [drag...] }); // shared_pointer_required
// after
await open_application(app, { background: true });
await pointer_sequence({ actions: [drag...] }); Defensive patterns
Strategy: validation
Validate before calling
// before shared-pointer gestures, confirm the session allows them
if (!sessionState.foregroundInput && wantsSharedPointer) {
throw new Error('open the session in background/shared mode first');
} Try / catch
try {
await pointer_sequence(drag);
} catch (e) {
if (e?.code === 'shared_pointer_required') {
// switch to accessibility action instead of hijacking the pointer
await a11yAction(target, 'AXPress');
} else throw e;
} Prevention
- Open sessions in background/shared mode when the script needs drags or global gestures.
- Never request foreground (exclusive) mode unless the user explicitly authorized it.
- Prefer accessibility element actions, which work in background mode without the shared pointer.
- Document per-session mode and gate shared-pointer tools on it.
When it happens
Trigger: Invoking a shared-pointer tool (e.g. pointer_sequence — nativeLease calls requireSharedPointer for it) while the session was opened with foreground/exclusive input instead of background mode, i.e. state.foregroundInput is false.
Common situations: Running the agent directly on the user's desktop (foreground session) and then attempting a drag; misconfigured session options that left background mode off; scripts written for a remote/separate-computer setup run locally in foreground mode.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- background preview capture failed
- no agent pointer button is held by this session
- no agent pointer position — mouse_move or left_mouse_down…
- no window at ( , ) — take a fresh screenshot and choose a…
- open_application first to choose which application receives…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/c6c38024e0e557a7.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/src/backends/darwin.mjs:367
// ---------- pointer input ----------
// Our qualified raw pointer path uses the shared event tap, which moves
// the user's real cursor. Process/window-directed mouse delivery has not
// passed the independent fixture. So the pointer path is:
// 1. accessibility action on the element under the point (quiet, exact),
// 2. otherwise refuse in background mode. Explicit foreground control
// permits a global gesture only when the bound application owns the
// window under the point. Restoring the cursor is not isolation.
// Every receipt says which of the two happened.
function mouseName(button) { return { left: "left", right: "right", middle: "middle" }[button] ?? "left"; }
function assertInScreen(x, y) {
if (!Number.isFinite(x) || !Number.isFinite(y)) throw new ExecError("coordinates must be finite numbers");
}
function buttonCode(button) { return button === "middle" ? 2 : button === "right" ? 1 : 0; }
function requireSharedPointer() {
if (!state.foregroundInput) throw Object.assign(new ExecError("This action needs the shared macOS pointer and was not sent in background mode. Use an accessibility action or a separate computer; foreground control requires exclusive desktop use authorized by the user."), { code: "shared_pointer_required" });
}
/** Refuse a global gesture whose landing point belongs to another application. */
async function assertOwnsPoint(x, y) {
if (!state.inputApp) throw new ExecError("open_application first to choose which application receives input");
const w = await native("window_at_point", { x, y });
if (!w?.found) throw new ExecError(`no window at (${x}, ${y}) — take a fresh screenshot and choose a point inside the target window`);
if (w.owner_pid !== state.inputApp.pid) {
throw new ExecError(`(${x}, ${y}) is covered by a window owned by ${w.owner_name || "another application"} (pid ${w.owner_pid}) — use an accessibility element target or a separate computer; no pointer input was sent`);
}
return w;
}
/** What a global gesture cost the user: their cursor, and briefly their foreground. */
function pointerCost(r) {
return {
pointer_moved: true,
pointer_restored: !!r?.restored,View on GitHub (pinned to 73e0f67d83)