wavetermdev/waveterm · error
err.Error()
Error message
err.Error()
What it means
HandleWs (pkg/web/ws.go:70) wraps HandleWsInternal; if the WebSocket upgrade or setup fails, the resulting error is written via http.Error with status 500. Any failure to establish the WS connection (bad handshake, internal setup error) surfaces as this plain-text 500.
Source
Thrown at pkg/web/ws.go:70
server.SetKeepAlivesEnabled(false)
log.Printf("[websocket] running websocket server on %s\n", listener.Addr())
err := server.Serve(listener)
if err != nil {
log.Printf("[websocket] error trying to run websocket server: %v\n", err)
}
}
var WebSocketUpgrader = websocket.Upgrader{
ReadBufferSize: 4 * 1024,
WriteBufferSize: 32 * 1024,
HandshakeTimeout: 1 * time.Second,
CheckOrigin: func(r *http.Request) bool { return true },
}
func HandleWs(w http.ResponseWriter, r *http.Request) {
err := HandleWsInternal(w, r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func getMessageType(jmsg map[string]any) string {
if str, ok := jmsg["type"].(string); ok {
return str
}
return ""
}
func getStringFromMap(jmsg map[string]any, key string) string {
if str, ok := jmsg[key].(string); ok {
return str
}
return ""
}
func processWSCommand(jmsg map[string]any, outputCh chan any, rpcInputCh chan baseds.RpcInputChType) {View on GitHub (pinned to a4447c1563)
Solutions
- Read err.Error() in the 500 response body to see the exact handshake/setup failure.
- Configure the reverse proxy to pass Upgrade and Connection headers for the /ws route.
- Ensure the client uses wss:// when the server is behind TLS and includes any required query parameters (e.g. idempotency token).
- Confirm the route is registered (HandleWs wired into the mux) and the request method is GET.
Example fix
// nginx before
location /ws { proxy_pass http://backend; }
// after
location /ws {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify the endpoint is reachable and supports upgrade before opening WS
const probe = await fetch(wsBaseUrl.replace("ws", "http"), {method: "GET"});
if (probe.status >= 500) throw new Error("ws endpoint not healthy"); Try / catch
try {
const sock = new WebSocket(wsUrl);
sock.onerror = (e) => console.error("ws handshake failed", e);
} catch (err) {
console.error("HandleWs returned 500:", err);
// fall back to polling or retry with corrected headers
} Prevention
- Configure proxies to forward Upgrade/Connection headers on the ws route.
- Use wss:// behind TLS and include required query params (e.g. idempotency token).
- Check the 500 response body; it contains the exact handshake failure reason.
When it happens
Trigger: HandleWsInternal returns an error — e.g. the websocket Upgrader fails the HTTP->WS handshake because required Upgrade/Connection headers are missing or stripped, or internal initialization inside HandleWsInternal fails.
Common situations: Reverse proxies not forwarding the Upgrade/Connection headers (nginx without proxy_set_header Upgrade $connection_upgrade), clients connecting over plain http where only https is served, an IdempotencyToken/query param missing in the WS URL.
Related errors
- recErr.Error()
- error getting wave file: + resp.statusText
- beginning of file
- procinfo: process not found
- integer overflow
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/d4aa2ba72d090cdd.
Report an issue: GitHub.