Hmbown/CodeWhale · error · ExecError

no running application with pid

Error message

no running application with pid ${pid}; call list_apps for the current processes

What it means

After trying to resolve the pid through the native helper (app_info), the backend found no running application with that pid and there is no name or bundle_id fallback to launch. It tells you to call list_apps for the current process list. Note this throw dereferences pid in the message, so it is only reachable when pid was provided (pid-only lookups that fail).

Solutions

  1. Call list_apps and use a currently valid pid or app name.
  2. Supply name or bundle_id alongside pid so the backend can fall back to launching via `open`.
  3. Refresh the pid after the app restarts instead of reusing a cached value.

Example fix

// before
await backend.open_application({ pid: stalePid });
// after
const apps = await backend.list_apps();
const app = apps.find(a => a.name === "Safari");
await backend.open_application({ pid: app.pid });
Defensive patterns

Strategy: validation

Validate before calling

const apps = await backend.list_apps();
if (!apps.some(a => a.pid === pid)) {
  throw new Error(`pid ${pid} is not running; refresh from list_apps`);
}
await backend.open_application({ pid });

Type guard

function pidIsLive(apps, pid) {
  return apps.some(a => a.pid === pid);
}

Try / catch

try {
  await backend.open_application({ pid });
} catch (e) {
  if (String(e.message).startsWith('no running application with pid')) {
    const apps = await backend.list_apps();
    // re-resolve and retry with a live pid or name
  } else throw e;
}

Prevention

When it happens

Trigger: open_application({ pid: N }) where no process with pid N is running (it exited, or the pid came from a stale list_apps result), and neither name nor bundle_id was supplied as a fallback.

Common situations: Agent caches a pid from an earlier list_apps call, the app crashes or is relaunched with a new pid, then a later open_application by pid fails; using a pid captured on a different machine/session.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/fb0966ce38344b6f. Report an issue: GitHub.

Appendix: source

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

    // Failed selection must not leave an earlier app armed for shared input.
    state.foregroundInput = false;
    state.inputApp = null;
    // pid is the most specific identity and the only one that separates two
    // processes of the same bundle (e.g. a second Chrome on its own profile),
    // so it wins when given.
    const find = {};
    if (pid) find.pid = pid; else if (bid) find.bundle_id = bid; else find.name = String(name).replace(/\.app$/, "");
    let p;
    // Binding an already-running app must not ask LaunchServices to reopen
    // it: reopen can raise windows even with open -g on some applications.
    if (!urlArg) {
      try { p = await native("app_info", { app_ref: find, activate }); }
      catch (error) {
        if (!error.message.includes("application not found")) throw error;
      }
    }
    if (!p?.found) {
      if (!name && !bid) throw new ExecError(`no running application with pid ${pid}; call list_apps for the current processes`);
      const args = [];
      if (urlArg) args.push(urlArg);
      if (bid) args.unshift("-b", bid); else args.unshift("-a", name);
      if (!activate) args.unshift("-g");
      const r = await runL("open", args, { timeoutMs: 25_000 });
      if (r.code !== 0) throw new ExecError(`open failed: ${r.stderr.trim().slice(0, 200)}`, r);
      await new Promise((res) => setTimeout(res, 600));
      p = await native("app_info", { app_ref: find, activate });
    }
    if (activate && p?.frontmost === false) throw Object.assign(new ExecError("The selected application did not become frontmost; no input mode was enabled. Continue with background control or wait for the user."), { code: "activation_not_confirmed" });
    if (p?.bundle_id === "net.codewhale.computer-use") throw Object.assign(new ExecError("The Computer Use setup and safety controls belong to the user and cannot be operated by this plugin."), { code: "protected_application" });
    // A bare executable has no bundle id; carrying an empty one would make the
    // identity unmatchable.
    state.inputApp = { pid: p.pid, ...(p.bundle_id ? { bundle_id: p.bundle_id } : {}) };
    state.foregroundInput = !!activate;
    return { launched: true, activate, keyboard_delivery: activate ? "foreground-guarded" : "process", input_scope: activate ? "shared-desktop" : "application", shared_pointer: !!activate, isolated_desktop: false, url: urlArg ?? null, resolved: p?.found ? { name: p.name, pid: p.pid, bundle_id: p.bundle_id, frontmost: p.frontmost } : null };
  }

View on GitHub (pinned to 433685b202)