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
- Retry the activation — a slow start often succeeds on a second attempt.
- Check local server logs/process to confirm the openwork-server actually started (crash, port conflict).
- Increase the retry budget/timeout in waitForReadyLocalOpenworkServerInfo if starts are routinely slow.
- 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
- Use exponential backoff with a generous total timeout for server readiness.
- Monitor the server process health, not just the info file.
- Pre-warm the local server at app startup before routes need it.
- Alert on port conflicts and stale state files.
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
- Timed out waiting for server health
- Agent context diagnostics timeout must be between 1 ms and 3
- Request timed out.
- Authorization for ${input.connectionName} did not finish. Co
- Connection lost
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/28842726645fcc66.
Report an issue: GitHub.