{"record":{"id":"2988646bc4e4f2a2","repo":"sipeed/picoclaw","slug":"request-failed-with-status-res-status","errorCode":null,"errorMessage":"Request failed with status ${res.status}","messagePattern":"Request failed with status (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"web/frontend/src/components/config/config-page.tsx","lineNumber":684,"sourceCode":"          trustedProxyCIDRsText: (\n            savedLauncherConfig.trusted_proxy_cidrs ?? []\n          ).join(\"\\n\"),\n          dashboardPassword: \"\",\n          dashboardPasswordConfirm: \"\",\n        }\n        savedLauncherForm = parsedLauncher\n        setLauncherForm(parsedLauncher)\n        setLauncherBaseline(parsedLauncher)\n        queryClient.setQueryData(\n          [\"system\", \"launcher-config\"],\n          savedLauncherConfig,\n        )\n      }\n\n      if (launcherPasswordDirty) {\n        const result = await postLauncherDashboardSetup(password, confirm)\n        if (!result.ok) {\n          throw new Error(result.error)\n        }\n\n        const clearedLauncherForm = savedLauncherForm ?? {\n          ...launcherForm,\n          dashboardPassword: \"\",\n          dashboardPasswordConfirm: \"\",\n        }\n        setLauncherForm(clearedLauncherForm)\n        if (savedLauncherForm) {\n          setLauncherBaseline(savedLauncherForm)\n        }\n      }\n\n      if (autoStartDirty) {\n        if (!autoStartSupported) {\n          throw new Error(t(\"pages.config.autostart_unsupported\"))\n        }\n        const status = await updateAutoStartEnabled(autoStartEnabled)","sourceCodeStart":666,"sourceCodeEnd":702,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/web/frontend/src/components/config/config-page.tsx#L666-L702","documentation":"This message is the fallback error string produced by readLauncherAuthError in web/frontend/src/api/launcher-auth.ts:74 when POST /api/auth/setup fails and the response body is not JSON containing an error field; it is then re-thrown by handleSave via throw new Error(result.error) at web/frontend/src/components/config/config-page.tsx:684 when result.ok is false. It means the dashboard-password setup endpoint rejected the request with an HTTP error status and no readable error message.","triggerScenarios":"POST /api/auth/setup returns 400 (password too weak/confirmation mismatch server-side), 409 (dashboard password already set — setup is one-time), 401/403 (auth constraints), or a proxy 502 with an HTML body, all without a JSON {error} payload.","commonSituations":"Trying to 'set' the password again after initial setup instead of using the change-password flow; reverse proxy intercepting /api/auth with an HTML error page; backend version whose setup endpoint validates differently than the frontend (e.g. stricter length); session cookie missing.","solutions":["Open the network tab, find POST /api/auth/setup, and read the status code — the message embeds it (e.g. 409)","For 409: the password is already configured; use the change/update password flow rather than setup","For 400: choose a stronger password (server-side rules may exceed the client's 8-char minimum) and ensure both fields match","For 502/HTML responses: fix the reverse proxy routing so /api/auth reaches the launcher backend"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const result = await postLauncherDashboardSetup(password, confirm)\nif (!result.ok) {\n  // result.error may be 'Request failed with status N' when the body had no JSON error\n  console.warn(\"setup failed:\", result.error)\n}","typeGuard":"type SetupResult = { ok: true } | { ok: false; error: string }\nfunction isSetupFailure(r: SetupResult): r is Extract<SetupResult, { ok: false }> {\n  return !r.ok\n}","tryCatchPattern":"try {\n  const result = await postLauncherDashboardSetup(password, confirm)\n  if (isSetupFailure(result)) {\n    setError(result.error) // includes the HTTP status when the server sent no JSON error\n  }\n} catch (err) {\n  setError(err instanceof Error ? err.message : \"Setup request failed\")\n}","preventionTips":["Backend: always return a JSON {error} body on setup failures so the status-only fallback never appears","Handle 409 explicitly in the UI: setup is one-time, direct users to change-password","Mirror backend password policy client-side so 400s become pre-validated"],"tags":["http","authentication","password","frontend","backend","api"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}