Skip to content

fix: resolve the workspace WS endpoint from PUBLIC_WS_URL in one place, not sixteen literals - #93

Merged
mpstaton merged 1 commit into
rebuild/turbo-rsbuildfrom
fix/ws-url-from-env
Aug 21, 2026
Merged

fix: resolve the workspace WS endpoint from PUBLIC_WS_URL in one place, not sixteen literals#93
mpstaton merged 1 commit into
rebuild/turbo-rsbuildfrom
fix/ws-url-from-env

Conversation

@mpstaton

Copy link
Copy Markdown
Member

Closes #91.

What was broken

Org Workbench rendered its chrome and nothing else on augment.didi.sh — no roster, no organizations, a red closed pill. Every remote declared const WS_URL = 'ws://localhost:3001/ws' and never read the environment, so a deployed surface opened its data socket against the visitor's laptop.

It could not have worked in prod for two independent reasons: wrong host, and ws:// from an https:// origin is blocked as mixed content. Local dev hid it perfectly, because the operator's machine really is running workspace-service on :3001.

Three of the sixteen affected remotes are deployed, so this took down the whole Augment-from-DB flow, not one surface.

The Railway config was already correct — all three services have PUBLIC_WS_URL=wss://ws.augment.didi.sh/ws today. The value simply landed where no source line read it. No variable changes are needed.

The fix

packages/workspace/src/ws-url.ts exports resolveWsUrl() / resolveHttpBase(), and TransportConfig.url becomes optional — omit it and the transport resolves from PUBLIC_WS_URL on each connect attempt.

That optionality is the part that matters: the failure mode was never a logic error, it was copy-paste into a new remote, and the copy-pasteable thing no longer exists. All 22 call sites were converted, including the two that had quietly got it right (chat, and corpora-curator's real client in curation.svelte.ts) so there is no second pattern to imitate. The WorkspaceSwitcher tooltip also stops claiming localhost is unreachable when the endpoint is elsewhere.

Verification

  • Bundle proof — built org-workbench with PUBLIC_WS_URL set; the resolver compiles to function d(){let e="wss://ws.augment.didi.sh/ws";return"string"==typeof e&&e.length>0?e:"ws://localhost:3001/ws"}. Prod value inlined, localhost only as the dead fallback branch.
  • Regression guard — new test sweeps apps/, shell/, packages/ for the literal and fails with the offending filenames. Planting the old line back into org-workbench makes it fail, so it is not vacuous.
  • svelte-check clean across all 17 surfaces; @augment-it/workspace suite 7/7.
  • Local dev stack HMR'd clean, zero build errors — the localhost fallback path still works.

Deploy note

PUBLIC_* is baked at build time, so after merge the three deployed remotes need railway redeploy --service <name> --from-source, not a restart: org-workbench, search-and-add, search-results.

🤖 Generated with Claude Code

https://claude.ai/code/session_017HuzSPdPK4QEhs7eztHgoC

…UBLIC_WS_URL in one place, not sixteen literals

Org Workbench rendered its chrome and nothing else on augment.didi.sh: no
roster, no organizations, a red `closed` pill in the corner. The cause was a
single line repeated across the app tree — every remote declared
`const WS_URL = 'ws://localhost:3001/ws'` and never read the environment, so a
deployed surface opened its data socket against the *visitor's* laptop. It could
not have worked in production for two independent reasons: the host is wrong,
and `ws://` from an `https://` origin is blocked as mixed content. Local dev hid
it perfectly, because the operator's machine really is running
workspace-service on :3001. Three of the sixteen affected remotes are deployed,
which took down the whole Augment-from-DB flow rather than one surface.

The endpoint now has exactly one home. `packages/workspace/src/ws-url.ts`
exports `resolveWsUrl()` and `resolveHttpBase()`, and `TransportConfig.url`
becomes optional — omit it and the transport resolves from PUBLIC_WS_URL on
every connect attempt. That is the part that makes the bug structurally
unavailable: the failure mode was never a logic error, it was copy-paste into a
new remote, and the copy-pasteable thing no longer exists. Every call site was
converted, including the two that had quietly got it right (chat, and
corpora-curator's real client in curation.svelte.ts) so there is no second
pattern to imitate, and the WorkspaceSwitcher tooltip stops telling operators
that localhost is unreachable when the endpoint is somewhere else entirely.

Verified by building org-workbench with PUBLIC_WS_URL set and reading the
emitted bundle: the resolver compiles to the prod endpoint with localhost left
only as the dead fallback branch. A new guard in the workspace suite sweeps
apps/, shell/, and packages/ for the literal and fails with the offending
filenames; planting the old line back into org-workbench makes it fail, so it
is not vacuous. svelte-check is clean across all 17 surfaces.

Deploy note: PUBLIC_* is baked at build time, so the three deployed remotes need
a rebuild, not a restart, once their variables are set.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017HuzSPdPK4QEhs7eztHgoC
@mpstaton
mpstaton merged commit 61c0e2c into rebuild/turbo-rsbuild Aug 21, 2026
17 of 18 checks passed
@mpstaton
mpstaton deleted the fix/ws-url-from-env branch August 21, 2026 20:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Every remote hardcodes the workspace WS to localhost — Org Workbench loads no data on augment.didi.sh

1 participant