iOfficeAI/AionUi · critical
[WebUI] Cannot start: aioncore is not running (globalThis.__
Error message
[WebUI] Cannot start: aioncore is not running (globalThis.__backendPort unset)
What it means
Thrown by the WebUI seeding path when globalThis.__backendPort is unset, i.e. the aioncore backend process has not been started (or its port was never recorded) before the WebUI initialization ran.
Source
Thrown at packages/desktop/src/process/bridge/webuiBridge.ts:55
const json = (await res.json()) as { data?: AdminUsernameResult | null };
return json.data?.username ?? 'admin';
} catch {
return 'admin';
}
}
/**
* On first Enable-WebUI click after a fresh install, the backend's users table
* holds the seeded `system_default_user` row with an empty password_hash.
* Probe /api/auth/status; if `needs_setup === true`, ask backend to generate
* and persist a random password, then stash the plaintext for Settings to show
* once. When the backend already has credentials (upgrade path handled by
* ensureAdminUser, or a prior Enable-WebUI), this is a no-op.
*/
async function maybeSeedInitialPassword(): Promise<void> {
const port = getBackendPort();
if (!port) {
throw new Error('[WebUI] Cannot start: aioncore is not running (globalThis.__backendPort unset)');
}
const statusRes = await fetch(`http://127.0.0.1:${port}/api/auth/status`);
if (!statusRes.ok) {
throw new Error(`[WebUI] /api/auth/status returned ${statusRes.status}`);
}
const statusJson = (await statusRes.json()) as { needs_setup?: boolean; data?: { needs_setup?: boolean } };
const needsSetup = statusJson.needs_setup ?? statusJson.data?.needs_setup ?? false;
if (!needsSetup) {
setDesktopWebUIInitialPassword(undefined);
return;
}
const resetRes = await fetch(`http://127.0.0.1:${port}/api/webui/reset-password`, { method: 'POST' });
if (!resetRes.ok) {
throw new Error(`[WebUI] /api/webui/reset-password returned ${resetRes.status}`);
}
const resetJson = (await resetRes.json()) as { data?: { new_password?: string }; new_password?: string };
const newPassword = resetJson.data?.new_password ?? resetJson.new_password;
if (!newPassword) {View on GitHub (pinned to 711aa0550e)
Solutions
- Ensure backendManager.start() has resolved and set __backendPort before initWebuiBridge runs
- Check the backend startup logs for a crash or early exit that prevented port assignment
- If the backend intentionally isn't running, skip WebUI seeding instead of letting it throw
- Make the error message actionable by including backend startup state in logs
Example fix
// before
const port = getBackendPort();
if (!port) {
throw new Error('[WebUI] Cannot start: aioncore is not running (globalThis.__backendPort unset)');
}
// after (await backend readiness instead of failing)
await waitForBackendPort(10_000);
const port = getBackendPort();
if (!port) {
throw new Error('[WebUI] Cannot start: aioncore is not running (globalThis.__backendPort unset)');
} Defensive patterns
Strategy: validation
Validate before calling
const port = (globalThis as { __backendPort?: number }).__backendPort;
if (!port) { /* defer WebUI init until backendManager reports ready */ } Type guard
function isBackendRunning(): boolean {
return typeof (globalThis as { __backendPort?: number }).__backendPort === 'number';
} Try / catch
catch (err) { log.error('[WebUI] init deferred:', err.message); /* schedule retry, don't crash app */ } Prevention
- Await backend-ready signals before initializing dependent bridges
- Expose backend health state, not just a global port variable
- Never assume startup ordering; make bridges idempotent/retryable
When it happens
Trigger: Calling maybeSeedInitialPassword (via initWebuiBridge) before backendManager.start() completed and set globalThis.__backendPort, or after the backend failed to start.
Common situations: Race between backend startup and WebUI bridge init, backend crash during startup, or running the WebUI bridge in a context where the backend was intentionally not spawned.
Related errors
- [WebUI] /api/auth/status returned ${statusRes.status}
- [WebUI] /api/webui/reset-password returned ${resetRes.status
- [WebUI] /api/webui/reset-password returned no new_password
- StartupArchitectureMismatchError
- File download failed (${response.status})
AI-assisted analysis of iOfficeAI/AionUi@711aa0550e (2026-08-28).
Data as JSON: /api/errors/9d893582f2632c10.
Report an issue: GitHub.