Hmbown/CodeWhale · error · ExecError
open failed
Error message
open failed: ${r.stderr.trim().slice(0, 200)} What it means
The macOS `open` command (run with a 25s timeout to launch the app by -a name or -b bundle_id, optionally a URL and -g for background) exited non-zero. The first 200 characters of its stderr are embedded in the message and the full result is attached to the ExecError.
Solutions
- Read the embedded stderr (and the attached result object) for the precise `open` failure reason.
- Verify the app exists: call list_apps, or check /Applications for the name/bundle id.
- Use the exact bundle_id (via osascript or list_apps) instead of a display name when names are ambiguous.
- If opening a URL, confirm a handler app is registered for its scheme.
Example fix
// before
await backend.open_application({ name: "FireFox" });
// after
await backend.open_application({ bundle_id: "org.mozilla.firefox" }); Defensive patterns
Strategy: try-catch
Validate before calling
const apps = await backend.list_apps();
if (!apps.some(a => a.name === appName || a.bundle_id === bundleId)) {
throw new Error(`app ${appName || bundleId} not installed/running`);
} Try / catch
try {
await backend.open_application({ name });
} catch (e) {
if (String(e.message).startsWith('open failed:')) {
console.error('`open` stderr:', e.message.slice('open failed:'.length));
} else throw e;
} Prevention
- Use exact bundle_ids obtained from list_apps instead of display names.
- Confirm the app is installed before calling open_application.
- Check URL schemes have a registered handler before opening URLs.
When it happens
Trigger: open_application falls back to `open` when app_info found no matching running app; `open` fails because the app name is misspelled, the bundle id does not exist, the app is not installed, or the URL scheme is not handled.
Common situations: Typos in app names ('FireFox' vs 'Firefox'); referring to an app not installed on the machine; bundle id copied from a different platform; opening a URL whose scheme has no registered handler; Spotlight indexing issues making -a lookups fail.
Related errors
- screencapture exited
- The background check requires the installed macOS app.
- app_denied
- application not found — call list_apps for exact names/pids
- background preview capture failed
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/8386983f6a850105.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/src/backends/darwin.mjs:570
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 };
}
// ---------- clipboard / cursor / waits ----------
async function readClipboard() {
const r = await runL("pbpaste", [], { timeoutMs: 5_000, maxBuffer: 4 * 1024 * 1024 });
return { text: r.stdout, encoding: "utf8" };
}
async function writeClipboard({ text }) {View on GitHub (pinned to 433685b202)