[Bug] Workshop stuck on INITIALIZING due to SPA routing of /api/ws #36

Closed
opened 2026-03-20 23:12:02 +00:00 by manus · 1 comment

Problem Description

The Timmy Tower Workshop, deployed at alexanderwhitestone.com/tower, consistently displays an "INITIALIZING" state and fails to connect to the backend WebSocket service. Investigation reveals that the Single Page Application (SPA) routing for /tower is inadvertently intercepting API calls directed to /api/ws, preventing the WebSocket connection from being established.

This issue directly impacts user experience, as the core functionality of the Workshop remains inaccessible, and users receive no feedback regarding the connection failure.

Reproduction Steps

  1. Navigate to alexanderwhitestone.com/tower.
  2. Observe the 3D scene loading.
  3. Note that the UI remains stuck on "INITIALIZING", and no agent activity or chat functionality is available.
  4. Inspect browser network requests; observe that WebSocket connection attempts to /api/ws are likely failing or being misrouted.

Expected Behavior

The Workshop should successfully establish a WebSocket connection to the backend, display agent activity, and enable chat interactions. API calls to /api/ws should be correctly routed to the backend service, bypassing the SPA routing for static assets.

Technical Details

  • Affected Repository: replit/timmy-tower
  • Relevant Files:
    • artifacts/api-server/src/app.ts: This file defines the Express application routing. Lines 81-82 handle the /tower route, serving index.html for all sub-paths. This might be over-eagerly catching /tower/api requests.
    • the-matrix/js/websocket.js: This frontend file attempts to establish the WebSocket connection to WS_URL, which resolves to /api/ws relative to the host.
  • Current Routing:
    app.use("/tower", express.static(towerDist));
    app.get("/tower/*splat", (_req, res) => res.sendFile(path.join(towerDist, "index.html")));
    
    The app.get("/tower/*splat") rule is likely catching /tower/api/ws requests, causing them to be served the index.html instead of being routed to the actual API endpoint.

Proposed Solution

Modify the Express routing in artifacts/api-server/src/app.ts to ensure that requests to /api/* (including /api/ws) are explicitly handled by the API router before the /tower static file serving and SPA fallback rule. This may involve reordering app.use("/api", router); or adding a more specific exclusion for API routes within the /tower handling.

Labels

bug, frontend, backend, routing, websocket

## Problem Description The Timmy Tower Workshop, deployed at `alexanderwhitestone.com/tower`, consistently displays an "INITIALIZING" state and fails to connect to the backend WebSocket service. Investigation reveals that the Single Page Application (SPA) routing for `/tower` is inadvertently intercepting API calls directed to `/api/ws`, preventing the WebSocket connection from being established. This issue directly impacts user experience, as the core functionality of the Workshop remains inaccessible, and users receive no feedback regarding the connection failure. ## Reproduction Steps 1. Navigate to `alexanderwhitestone.com/tower`. 2. Observe the 3D scene loading. 3. Note that the UI remains stuck on "INITIALIZING", and no agent activity or chat functionality is available. 4. Inspect browser network requests; observe that WebSocket connection attempts to `/api/ws` are likely failing or being misrouted. ## Expected Behavior The Workshop should successfully establish a WebSocket connection to the backend, display agent activity, and enable chat interactions. API calls to `/api/ws` should be correctly routed to the backend service, bypassing the SPA routing for static assets. ## Technical Details - **Affected Repository:** `replit/timmy-tower` - **Relevant Files:** - `artifacts/api-server/src/app.ts`: This file defines the Express application routing. Lines 81-82 handle the `/tower` route, serving `index.html` for all sub-paths. This might be over-eagerly catching `/tower/api` requests. - `the-matrix/js/websocket.js`: This frontend file attempts to establish the WebSocket connection to `WS_URL`, which resolves to `/api/ws` relative to the host. - **Current Routing:** ```typescript app.use("/tower", express.static(towerDist)); app.get("/tower/*splat", (_req, res) => res.sendFile(path.join(towerDist, "index.html"))); ``` The `app.get("/tower/*splat")` rule is likely catching `/tower/api/ws` requests, causing them to be served the `index.html` instead of being routed to the actual API endpoint. ## Proposed Solution Modify the Express routing in `artifacts/api-server/src/app.ts` to ensure that requests to `/api/*` (including `/api/ws`) are explicitly handled by the API router *before* the `/tower` static file serving and SPA fallback rule. This may involve reordering `app.use("/api", router);` or adding a more specific exclusion for API routes within the `/tower` handling. ## Labels `bug`, `frontend`, `backend`, `routing`, `websocket`
gemini was assigned by Rockachopa 2026-03-22 23:37:31 +00:00
gemini was unassigned by claude 2026-03-22 23:37:32 +00:00
claude self-assigned this 2026-03-22 23:37:32 +00:00
Collaborator

PR created: http://143.198.27.163:3000/replit/timmy-tower/pulls/81

The /tower/*splat SPA fallback in Express 5 was catching all sub-paths including /tower/api/ws, serving index.html instead of letting the request reach the WebSocket server. Added a guard that calls next() for paths starting with api/ so they fall through to the API router / ws server.

PR created: http://143.198.27.163:3000/replit/timmy-tower/pulls/81 The `/tower/*splat` SPA fallback in Express 5 was catching all sub-paths including `/tower/api/ws`, serving `index.html` instead of letting the request reach the WebSocket server. Added a guard that calls `next()` for paths starting with `api/` so they fall through to the API router / ws server.
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: replit/timmy-tower#36