different-ai/openwork · error

Electron eval relaunch helper is unavailable.

Error message

Electron eval relaunch helper is unavailable.

What it means

evalRelaunchDesktopApp uses the dev-only bridge API `window.__OPENWORK_ELECTRON__.dev.evalRelaunch`, which relaunches the app in a controlled way for eval/E2E flows. If that helper is undefined — production builds strip dev APIs, or the app is not the Electron build — the function throws this dedicated message instead of returning a bogus result.

Source

Thrown at apps/app/src/app/lib/desktop.ts:535

  const result = await invokeElectronHelper("__applyBrandAppName", appName);
  return result.appName;
}

export async function applyBrandIcon(url: string | null): Promise<BrandIconApplyResult> {
  const apply = typeof window !== "undefined" ? window.__OPENWORK_ELECTRON__?.brandIcon?.apply : undefined;
  if (!apply) return { ok: false, reason: "bridge-unavailable" };
  return apply(url);
}

export async function getBrandIconState(): Promise<BrandIconState | null> {
  const getState = typeof window !== "undefined" ? window.__OPENWORK_ELECTRON__?.brandIcon?.getState : undefined;
  return getState ? getState() : null;
}

export async function evalRelaunchDesktopApp(): Promise<EvalRelaunchResult> {
  const relaunch = typeof window !== "undefined" ? window.__OPENWORK_ELECTRON__?.dev?.evalRelaunch : undefined;
  if (!relaunch) {
    throw new Error("Electron eval relaunch helper is unavailable.");
  }
  return relaunch();
}

export type DesktopApplication = {
  name: string;
  appPath: string;
  icon: string | null;
};

export async function getDesktopApplicationsForFile(target: string): Promise<DesktopApplication[]> {
  return invokeElectronHelper("__getApplicationsForFile", target);
}

export async function openDesktopWithApp(target: string, appPath: string): Promise<void> {
  const result = await invokeElectronHelper("__openWithApp", target, appPath);
  if (typeof result === "string" && result.trim()) {
    throw new Error(result);

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Use the development Electron build that exposes `dev.evalRelaunch` for eval/test runs.
  2. In production flows call the stable `relaunchDesktopApp()` (shell.relaunch) instead of the eval helper.
  3. Guard the caller: check `window.__OPENWORK_ELECTRON__?.dev?.evalRelaunch` first and fall back to the standard relaunch or surface 'not supported in this build'.
  4. In tests, polyfill the dev bridge: `window.__OPENWORK_ELECTRON__.dev = { evalRelaunch: async () => ({ ... }) }`.

Example fix

// before
await evalRelaunchDesktopApp();

// after
if (window.__OPENWORK_ELECTRON__?.dev?.evalRelaunch) {
  await evalRelaunchDesktopApp();
} else {
  await relaunchDesktopApp();
}
Defensive patterns

Strategy: fallback

Validate before calling

const hasEvalRelaunch = typeof window !== "undefined" && typeof window.__OPENWORK_ELECTRON__?.dev?.evalRelaunch === "function";

Type guard

function supportsEvalRelaunch(w: Window): boolean {
  return typeof w.__OPENWORK_ELECTRON__?.dev?.evalRelaunch === "function";
}

Try / catch

try {
  await evalRelaunchDesktopApp();
} catch (err) {
  if (err instanceof Error && err.message.includes("eval relaunch helper is unavailable")) {
    await relaunchDesktopApp(); // production-safe path
  } else { throw err; }
}

Prevention

When it happens

Trigger: Calling evalRelaunchDesktopApp (e.g. from relaunchAction) when `window.__OPENWORK_ELECTRON__` is undefined, the preload does not expose the `dev.evalRelaunch` namespace, or the desktop app is a production build where the dev-only relaunch helper is omitted.

Common situations: Running an eval/E2E test suite against a packaged production app that lacks the dev bridge; running the web build locally where no bridge exists at all; an Electron preload updated so dev APIs moved or were renamed; invoking relaunch from the UI in a store/distribution build instead of the dev build.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/3f5dd318d182ba10. Report an issue: GitHub.