different-ai/openwork · critical

OpenWork server did not become ready after activation.

Error message

OpenWork server did not become ready after activation.

What it means

Thrown by ensureDesktopLocalOpenworkConnection after the bounded retry loop for waitForReadyLocalOpenworkServerInfo gives up. The local OpenWork server publishes its base URL and tokens asynchronously after a (re)start; if the info never becomes ready within the retries, this error reports that the server did not become ready after activation.

Source

Thrown at apps/app/src/react-app/shell/desktop-local-openwork.ts:174

  try {
    const engine = await engineInfo().catch(() => null) as EngineInfo | null;
    let startedEngine = false;
    if (!engine?.running || !engine.baseUrl) {
      await engineStart(workspaceRoot, {
        runtime: "direct",
        workspacePaths,
        openworkRemoteAccess: readOpenworkServerSettings().remoteAccessEnabled === true,
      });
      startedEngine = true;
    }

    // The server publishes its base URL and tokens asynchronously after a
    // (re)start, so gate on observed readiness with bounded retries instead
    // of failing on the first empty answer.
    const info = await waitForReadyLocalOpenworkServerInfo();
    if (!isReadyLocalOpenworkServerInfo(info) || !info.baseUrl) {
      throw new Error("OpenWork server did not become ready after activation.");
    }

    const previousSettings = readOpenworkServerSettings();
    const nextSettings = writeOpenworkServerSettings({
      urlOverride: info.baseUrl,
      token: info.ownerToken?.trim() || info.clientToken?.trim() || undefined,
      hostToken: info.hostToken?.trim() || undefined,
      portOverride: info.port ?? undefined,
      remoteAccessEnabled: info.remoteAccessEnabled === true,
    });
    if (startedEngine || openworkServerSettingsChanged(previousSettings, nextSettings)) {
      emitOpenworkSettingsChanged();
    }

    recordInspectorEvent("route.local_openwork.ensure.success", {
      route: options.route,
      workspaceId: workspace.id,
      workspaceRoot,

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Retry the activation — a slow start often succeeds on a second attempt.
  2. Check local server logs/process to confirm the openwork-server actually started (crash, port conflict).
  3. Increase the retry budget/timeout in waitForReadyLocalOpenworkServerInfo if starts are routinely slow.
  4. Fully restart the desktop app so the local server is launched fresh.

Example fix

// before
if (!isReadyLocalOpenworkServerInfo(info) || !info.baseUrl) {
  throw new Error("OpenWork server did not become ready after activation.");
}
// after — one extra explicit wait before failing
if (!isReadyLocalOpenworkServerInfo(info) || !info.baseUrl) {
  info = await waitForReadyLocalOpenworkServerInfo({ extraTimeoutMs: 15000 });
  if (!isReadyLocalOpenworkServerInfo(info) || !info.baseUrl) throw new Error("OpenWork server did not become ready after activation.");
}
Defensive patterns

Strategy: retry

Validate before calling

const ready = await isLocalOpenworkServerInfoReady();
if (!ready) await retryActivationWithBackoff();

Type guard

function isServerInfoReady(info: LocalOpenworkServerInfo | null): info is LocalOpenworkServerInfo & { baseUrl: string } {
  return info != null && typeof info.baseUrl === "string" && info.baseUrl.length > 0;
}

Try / catch

try {
  await ensureDesktopLocalOpenworkConnection(options);
} catch (error) {
  if (error.message.includes("did not become ready")) {
    await retryWithBackoff(() => ensureDesktopLocalOpenworkConnection(options), 3);
  } else throw error;
}

Prevention

When it happens

Trigger: Calling ensureDesktopLocalOpenworkConnection (from useWorkspaceRouteState, handleCreateWorkspace, or SettingsRouteContent) right after server start/restart when the info file with baseUrl/token never appears before retries are exhausted.

Common situations: Slow machine or first-run install where the local server takes longer than the retry budget to boot; server process crashed during startup; stale server state file deleted while the process is dead; port conflicts preventing the server from publishing its URL.

Related errors


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