different-ai/openwork · error
Failed to open browser
Error message
Failed to open browser
What it means
openDesktopUrl first validates the URL, then calls the Electron shell bridge's openExternal. If the bridge reports a failure (`result.ok === false`), the error thrown is the bridge's own `result.error`, or the generic 'Failed to open browser' when the bridge supplied no error detail. It signals the OS-level open of the default browser failed, not a URL problem.
Source
Thrown at apps/app/src/app/lib/desktop.ts:489
let parsed: URL;
try {
parsed = new URL(url);
} catch {
throw new Error("Only valid web links can be opened externally.");
}
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
throw new Error(`External URL protocol "${parsed.protocol}" is not allowed.`);
}
return parsed.toString();
}
export async function openDesktopUrl(url: string): Promise<void> {
const safeUrl = assertDesktopWebUrl(url);
const openExternal = window.__OPENWORK_ELECTRON__?.shell?.openExternal;
if (openExternal) {
const result = await openExternal(safeUrl);
if (result && result.ok === false) {
throw new Error(result.error ?? "Failed to open browser");
}
return;
}
if (typeof window !== "undefined") {
window.open(safeUrl, "_blank", "noopener,noreferrer");
}
}
export async function openDesktopPath(target: string): Promise<void> {
const result = await invokeElectronHelper("__openPath", target);
if (typeof result === "string" && result.trim()) {
throw new Error(result);
}
}
export async function revealDesktopItemInDir(target: string): Promise<void> {
const result = await invokeElectronHelper("__revealItemInDir", target);
if (typeof result === "string" && result.trim()) {View on GitHub (pinned to 2b7df46e8a)
Solutions
- Set/repair the OS default browser (Settings → Default apps, or `xdg-settings set default-web-browser firefox.desktop` on Linux) and retry.
- Use the fallback path by ensuring the bridge is absent only in web contexts — in web builds window.open handles it; if in Electron and it persistently fails, fall back to `window.open(safeUrl, "_blank", "noopener,noreferrer")` in the renderer.
- Check the Electron main process logs around shell.openExternal for the underlying OS error.
- Retry after restarting the desktop app if the failure followed a browser uninstall/update while the app was running.
Example fix
// before
await openDesktopUrl(link);
// after
try {
await openDesktopUrl(link);
} catch (err) {
console.error("openExternal failed, falling back", err);
window.open(link, "_blank", "noopener,noreferrer");
} Defensive patterns
Strategy: fallback
Try / catch
try {
await openDesktopUrl(url);
} catch (err) {
console.error("openExternal failed", err);
window.open(url, "_blank", "noopener,noreferrer");
} Prevention
- Ensure the OS has a working default browser configured, especially on Linux/CI machines.
- Fall back to window.open in the renderer whenever the Electron bridge open fails.
- Watch Electron main-process logs for shell.openExternal errors after browser updates.
- On sandboxed (Flatpak/Snap) builds, verify portal permissions for opening external apps.
When it happens
Trigger: `window.__OPENWORK_ELECTRON__.shell.openExternal(safeUrl)` resolving with `{ ok: false }` and no `error` message — e.g. the main process failed to spawn the default browser, no browser is registered, or the OS handler invocation returned an error without a detail string.
Common situations: Linux desktop environments without a default browser configured (xdg-open fails); sandboxed/flatpak builds missing portal permissions to launch external apps; a corporate machine with locked-down default app associations; a stale/removed default browser.
Related errors
- Electron desktop helper is unavailable: ${command}
- ${result}
- Electron desktop helper is unavailable: ${prop}
- Only valid web links can be opened externally.
- External URL protocol "${parsed.protocol}" is not allowed.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/f885442b96e0c8ec.
Report an issue: GitHub.