different-ai/openwork · error
Electron desktop helper is unavailable: ${command}
Error message
Electron desktop helper is unavailable: ${command} What it means
invokeElectronHelper is the typed wrapper around the Electron preload bridge `window.__OPENWORK_ELECTRON__.invokeDesktop`. When that bridge is not present on `window` — i.e. the code is not running inside the Electron renderer with the preload script loaded — there is no way to service the command, so the wrapper throws immediately with the requested command name to make the missing-runtime cause obvious. It is a deliberate fail-fast instead of silently returning undefined.
Source
Thrown at apps/app/src/app/lib/desktop.ts:233
platform?: "darwin" | "linux" | "windows";
version?: string;
evalFatalBootstrapFailure?: string | null;
};
};
}
}
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
async function invokeElectronHelper<C extends DesktopCommandName>(
command: C,
...args: DesktopCommandArgs<C>
): Promise<DesktopCommandResult<C>> {
const invokeDesktop = window.__OPENWORK_ELECTRON__?.invokeDesktop;
if (!invokeDesktop) {
throw new Error(`Electron desktop helper is unavailable: ${command}`);
}
return (await invokeDesktop(command, ...args)) as DesktopCommandResult<C>;
}
// Pure utility — resolves the selected workspace ID from a workspace list
// payload, handling legacy fields.
export function resolveWorkspaceListSelectedId(
list: Pick<WorkspaceList, "selectedId" | "activeId"> | null | undefined,
): string {
return list?.selectedId?.trim() || list?.activeId?.trim() || "";
}
// ---------------------------------------------------------------------------
// Desktop bridge (Electron IPC proxy)
// ---------------------------------------------------------------------------
// All bridge methods are implemented via invokeDesktop IPC. The Proxy
// automatically maps property access to `invokeDesktop(propertyName, ...args)`.View on GitHub (pinned to 2b7df46e8a)
Solutions
- Run the app in the Electron desktop build (or verify the Electron preload script is loaded) so window.__OPENWORK_ELECTRON__.invokeDesktop exists before invoking the command.
- Guard the call site with a capability check such as `if (!window.__OPENWORK_ELECTRON__?.invokeDesktop) return;` and show a web-appropriate UI instead of the desktop action.
- In tests/storybook, polyfill `window.__OPENWORK_ELECTRON__` with a stub invokeDesktop that returns canned DesktopCommandResult values.
- If you are in Electron but still see this, check preload path registration (webPreferences.preload) and console errors from the preload script.
Example fix
// before
const icon = await getDesktopFileIcon(path);
// after
if (!window.__OPENWORK_ELECTRON__?.invokeDesktop) {
console.warn("Desktop helper unavailable; skipping file icon.");
return null;
}
const icon = await getDesktopFileIcon(path); Defensive patterns
Strategy: try-catch
Validate before calling
const canUseDesktop = typeof window !== "undefined" && typeof window.__OPENWORK_ELECTRON__?.invokeDesktop === "function";
Type guard
function hasElectronBridge(w: unknown): w is { __OPENWORK_ELECTRON__: { invokeDesktop: (...args: unknown[]) => Promise<unknown> } } {
return typeof window === "object" &&
typeof (window as { __OPENWORK_ELECTRON__?: unknown }).__OPENWORK_ELECTRON__ === "object" &&
typeof (window as { __OPENWORK_ELECTRON__?: { invokeDesktop?: unknown } }).__OPENWORK_ELECTRON__?.invokeDesktop === "function";
} Try / catch
try {
return await invokeElectronHelper("getDesktopFileIcon", path);
} catch (err) {
if (err instanceof Error && err.message.startsWith("Electron desktop helper is unavailable")) {
return null; // web build: no desktop icons
}
throw err;
} Prevention
- Gate all desktop-only UI behind a single isDesktopRuntime() capability check.
- Mock window.__OPENWORK_ELECTRON__ in test/storybook setups.
- Never call desktop helpers during SSR/prerender; guard with typeof window !== "undefined".
- Keep preload registration (webPreferences.preload) verified in app startup checks.
When it happens
Trigger: Any typed desktop command routed through invokeElectronHelper — cancel, desktopUploadMultipart, desktopDownloadBinary, result, getDesktopFileIcon, getDesktopApplicationsForFile — executed while `window.__OPENWORK_ELECTRON__` or its `invokeDesktop` method is undefined, such as in a plain browser build, during SSR/SSR hydration, before the Electron preload has attached the bridge, or in an old desktop build lacking the API.
Common situations: Running the web (non-Electron) build of the app and clicking a desktop-only action like 'Reveal in Finder' or a file download that uses the desktop multipart upload; an Electron app updated to a renderer whose preload script failed to load (e.g. contextIsolation/sandbox changes) so the bridge never registers; unit or Storybook tests that import desktop.ts and render components without mocking the window bridge.
Related errors
- Electron desktop helper is unavailable: ${prop}
- Failed to open browser
- ${result}
- 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/cc88dda65041d811.
Report an issue: GitHub.