different-ai/openwork · critical

OpenWork server did not report a base URL after startup.

Error message

OpenWork server did not report a base URL after startup.

What it means

The second check in assertOpenworkServerReady(): the server reports running but info.baseUrl is falsy. The app needs the server's HTTP base URL to route API/IPC requests; without it the server is unusable, so startup is treated as failed with this error.

Source

Thrown at apps/desktop/electron/main.mjs:1378

}

async function disposeRuntimeBeforeQuit() {
  if (runtimeDisposedForQuit || runtimeDisposeInProgress) return;
  runtimeDisposeInProgress = true;
  try {
    await runtimeManager.dispose().catch(() => undefined);
    runtimeDisposedForQuit = true;
  } finally {
    runtimeDisposeInProgress = false;
  }
}

function assertOpenworkServerReady(info) {
  if (!info?.running) {
    throw new Error("OpenWork server did not stay running after startup.");
  }
  if (!info.baseUrl) {
    throw new Error("OpenWork server did not report a base URL after startup.");
  }
  if (!info.ownerToken && !info.clientToken) {
    throw new Error("OpenWork server did not report an access token after startup.");
  }
  return info;
}

async function bootRuntimeForSelectedWorkspace() {
  if (typeof process.env.OPENWORK_EVAL_FATAL_DESKTOP_BOOTSTRAP_FAILURE === "string") {
    throw new Error(process.env.OPENWORK_EVAL_FATAL_DESKTOP_BOOTSTRAP_FAILURE);
  }
  const list = await workspaceStore.readWorkspaceState();
  const selectedId = list.selectedId || list.activeId || list.workspaces[0]?.id || "";
  const workspace = selectedId
    ? list.workspaces.find((entry) => entry?.id === selectedId)
    : list.workspaces[0];
  const workspaceRoot = String(workspace?.path ?? "").trim();
  if (!workspaceRoot || workspace?.workspaceType === "remote") {

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Ensure the bundled server version matches the runtime manager's expected status payload (baseUrl field present).
  2. Force server state regeneration by clearing the cached server info in userData and restarting.
  3. Retry the status read after a short delay if the server hadn't finished announcing its URL.
  4. Log the raw server status object when baseUrl is missing to pinpoint the handshake gap.

Example fix

// before
assertOpenworkServerReady(info); // throws: no baseUrl
// after
if (!info?.running) throw new Error('server not running');
if (!info.baseUrl) {
  info = await waitFor(() => getStatus().then(s => s.baseUrl), 5_000);
}
assertOpenworkServerReady(info);
Defensive patterns

Strategy: validation

Validate before calling

if (!info?.running) throw new Error('server not running');
if (!info.baseUrl || !/^https?:\/\//.test(info.baseUrl)) {
  throw new Error('server did not report a usable baseUrl');
}

Type guard

function hasBaseUrl(info) {
  return typeof info?.baseUrl === 'string' && info.baseUrl.length > 0;
}

Try / catch

try {
  assertOpenworkServerReady(info);
} catch (err) {
  if (String(err.message).includes('base URL')) {
    console.error('Server running but no baseUrl — check runtime/server version handshake.');
  } else throw err;
}

Prevention

When it happens

Trigger: info.running is true but baseUrl is missing/empty — server started without reporting its bound address, the runtime handshake omitted baseUrl (version mismatch between runtime manager and server), or the URL was cleared when reading server state.

Common situations: Server bound to an ephemeral/unix socket path that wasn't surfaced as a URL; older server build not emitting baseUrl in its status payload; state file in userData missing the baseUrl field after an upgrade; race where status is read before the server announces its address.

Related errors


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