fix: accept WebSocket before validation to prevent opaque 403 errors

All WebSocket endpoints now call websocket.accept() before any
validation checks. Previously, closing the connection before accepting
caused Starlette to return an opaque HTTP 403 instead of a meaningful
error message.

Changes:
- Server: Accept WebSocket first, then send JSON error + close with
  4xxx code if validation fails (expand, spec, assistant, terminal,
  main project WS)
- Server: ConnectionManager.connect() no longer calls accept() to
  avoid double-accept
- UI: Gate expand button and keyboard shortcut on hasSpec
- UI: Skip WebSocket reconnection on application error codes (4000-4999)
- UI: Update keyboard shortcuts help text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
nioasoft
2026-02-05 21:08:46 +02:00
parent 035e8fdfca
commit 70131f2271
2 changed files with 3 additions and 8 deletions

View File

@@ -225,9 +225,7 @@ async def terminal_websocket(websocket: WebSocket, project_name: str, terminal_i
await websocket.accept()
# Validate project name
try:
project_name = validate_project_name(project_name)
except Exception:
if not validate_project_name(project_name):
await websocket.send_json({"type": "error", "message": "Invalid project name"})
await websocket.close(
code=TerminalCloseCode.INVALID_PROJECT_NAME, reason="Invalid project name"