iOfficeAI/AionUi · error
[WebUI] /api/webui/reset-password returned ${resetRes.status
Error message
[WebUI] /api/webui/reset-password returned ${resetRes.status} What it means
Thrown when POST /api/webui/reset-password on the local backend returns a non-2xx status during WebUI initial-password seeding. The HTTP status is included in the message.
Source
Thrown at packages/desktop/src/process/bridge/webuiBridge.ts:69
*/
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) {
throw new Error('[WebUI] /api/webui/reset-password returned no new_password');
}
setDesktopWebUIInitialPassword(newPassword);
}
export function initWebuiBridge(): void {
ipcBridge.webui.getStatus.provider(async () => {
const snapshot = getDesktopWebUIStatus();
const adminUsername = await fetchAdminUsername();
return { ...snapshot, adminUsername };
});
ipcBridge.webui.start.provider(async (params) => {
await maybeSeedInitialPassword();View on GitHub (pinned to 711aa0550e)
Solutions
- Re-check /api/auth/status — if needs_setup flipped to false, seeding should be skipped, not reset
- curl -X POST the reset-password endpoint and read the response body for the backend's error detail
- Check backend logs for the failed reset (DB errors, validation errors)
- Confirm backend version compatibility with the desktop client
Defensive patterns
Strategy: retry
Validate before calling
const status = await fetch(`http://127.0.0.1:${port}/api/auth/status`).then((r) => r.json());
if (!status.needs_setup && !status.data?.needs_setup) { /* skip reset: nothing to seed */ } Try / catch
catch (err) {
if (/reset-password returned/.test(err.message)) {
const s = await fetchStatus(); // maybe setup completed elsewhere
if (!needsSetup(s)) return; // benign race
}
throw err;
} Prevention
- Re-verify needs_setup immediately before resetting
- Treat concurrent seeding as a benign race
- Contract-test the reset endpoint between desktop and backend releases
When it happens
Trigger: The backend responds 4xx/5xx to the unauthenticated reset-password request — e.g. the endpoint rejects the call because setup is not actually pending, or the backend errors while resetting.
Common situations: Race where another process already completed setup between the status check and the reset call, backend version mismatch removing/changing the endpoint, or backend internal error (DB locked/corrupt).
Related errors
- [WebUI] /api/auth/status returned ${statusRes.status}
- [WebUI] /api/webui/reset-password returned no new_password
- update.errors.githubApiFailed
- update.errors.cdnManifestFailed
- update.errors.downloadFailed
AI-assisted analysis of iOfficeAI/AionUi@711aa0550e (2026-08-28).
Data as JSON: /api/errors/1bb02a55fcad44f7.
Report an issue: GitHub.