elegant-branch-54423
05/26/2026, 7:01 PMquick-window-91705
05/26/2026, 7:01 PMelegant-branch-54423
05/26/2026, 7:02 PMelegant-branch-54423
05/26/2026, 7:06 PMancient-car-4311
05/26/2026, 7:06 PMelegant-branch-54423
05/26/2026, 7:07 PMgit clone <https://github.com/OpenHands/agent-canvas.git>
cd agent-canvas
npm install
npm run devhundreds-twilight-32833
05/26/2026, 7:19 PMelegant-branch-54423
05/26/2026, 7:20 PMhundreds-twilight-32833
05/26/2026, 7:25 PMhundreds-twilight-32833
05/26/2026, 7:42 PMelegant-branch-54423
05/26/2026, 7:43 PMhundreds-twilight-32833
05/26/2026, 7:52 PMelegant-branch-54423
05/26/2026, 8:08 PMlocalStorage.clear() is not enough. If you click Application > Clear Site Data , that did the trick for me.
Are we storing / have we stored data in the browser outside of localStorage?quick-window-91705
05/26/2026, 8:43 PMnutritious-balloon-65098
05/26/2026, 8:44 PMnutritious-balloon-65098
05/26/2026, 8:53 PMdev-with-automation.mjs and dev-safe.mjs) set VITE_BACKEND_BASE_URL: "<http://127.0.0.1:${port}>", which Vite bakes at compile-time into the JS bundle. On first page load, the frontend seeds openhands-backends in localStorage with host: "<http://127.0.0.1:8000>". When the browser opens the app at <http://localhost:8000>, every API call goes cross-origin to <http://127.0.0.1:8000> — which the browser treats as a different origin per CORS spec — and the ingress has no Access-Control-Allow-Origin header.
Why localStorage.clear() doesn't fix it: Clearing localStorage removes openhands-backends, but the page immediately re-seeds it on reload — reading VITE_BACKEND_BASE_URL from the same cached JS bundle — so it writes <http://127.0.0.1:8000> right back. Nothing changes.
Why "Clear Site Data" fixes it: It also purges the browser's HTTP cache, forcing a re-download of the JS bundle from the dev server. If the user had pulled a code fix that changed VITE_BACKEND_BASE_URL to "", the fresh bundle now makes getAgentServerBaseUrl() fall back to window.location.origin (localhost:8000), so the re-seeded backend is same-origin and CORS is avoided.
The proper fix (in branch origin/fix/remote-loopback-backend-origin, not yet merged, 157 commits behind main): set VITE_BACKEND_BASE_URL: "" in both dev scripts. The Vite server-side proxy (VITE_BACKEND_HOST) already handles routing /api/* to the backend — the client-side env var should be empty so browser fetches stay same-origin.
Also missing: a one-time migration in `storage.ts`'s readStoredBackends() to automatically normalize stale 127.0.0.1 hosts to match window.location.hostname, so existing users don't need to manually clear anything after the fix lands.