Hmbown/CodeWhale · error · ExecError

( , ) is covered by a window owned by (pid ) — use an…

Error message

(${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

What it means

assertOwnsPoint refuses to send a global pointer gesture when the window at the target point belongs to a different process than the application opened via open_application. This guard prevents sending synthetic clicks/gestures into another app's UI, which could misfire on unrelated windows. No pointer input was sent, so the caller's intent was not executed.

Solutions

  1. Take a fresh screenshot and re-target coordinates to a point visibly inside the bound application's window
  2. Call open_application for the owning app (or re-bind state.inputApp) before sending pointer input
  3. Switch to an accessibility element target (hit_test / a11y strategy) that needs no pointer
  4. Use a separate computer-use session scoped to the app that actually owns the point

Example fix

// before
await click(500, 400); // point may be covered by another app
// after
const shot = await screenshot(); // fresh observation
await click(shot.targetX, shot.targetY); // verified inside bound app
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await click(x, y);
} catch (e) {
  if (e instanceof ExecError && /covered by a window owned by/.test(e.message)) {
    const shot = await screenshot();
    // re-target coordinates from the fresh screenshot or rebind via open_application
  } else throw e;
}

Prevention

When it happens

Trigger: Calling a global gesture/click API with coordinates where the topmost window's owner_pid differs from state.inputApp.pid, e.g. after the target window moved, closed, was occluded, or the point was never inside the bound app.

Common situations: Stale screenshot coordinates after the user switched apps; the target window is covered by a dialog/overlay from another process; the caller forgot to call open_application first and is clicking on the desktop or another app.

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


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

Appendix: source

Thrown at crates/tui/plugins/computer-use/src/backends/darwin.mjs:376

  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,
      foreground_taken: !!r?.foreground_taken,
      ...(r?.foreground_before ? { foreground_before: r.foreground_before } : {}),
      ...(r?.foreground_after ? { foreground_after: r.foreground_after } : {}),
      ...(Number.isFinite(r?.yield_ms) && r.yield_ms > 0 ? { yield_ms: r.yield_ms } : {}),
    };
  }

  async function gesture(steps, { restore = true, guard = null } = {}) {
    requireSharedPointer();

View on GitHub (pinned to 73e0f67d83)