From 241c324b138422963ba615556487e7d96e8274c0 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Thu, 4 Jun 2026 01:36:43 +0200 Subject: [PATCH] fix: trim terminal bearer token so whitespace can't break the WebSocket A trailing space in the Open Terminal bearer token broke only the interactive terminal: HTTP calls put the token in the Authorization header, where the spec strips trailing whitespace, so the connection test, file listing and tool calls all worked. The terminal WebSocket can't set headers from the browser, so it sends the token inside a JSON auth message that preserves the space verbatim, failing auth with [Connection closed]. Normalize the key on save so whitespace never enters storage, and trim it in the WebSocket auth message so existing saved configs work without re-saving. Co-Authored-By: Claude Opus 4.8 (1M context) Fixes #25613 --- src/lib/components/AddTerminalServerModal.svelte | 2 ++ src/lib/components/chat/XTerminal.svelte | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/components/AddTerminalServerModal.svelte b/src/lib/components/AddTerminalServerModal.svelte index e7c0236eb6..82c449f71b 100644 --- a/src/lib/components/AddTerminalServerModal.svelte +++ b/src/lib/components/AddTerminalServerModal.svelte @@ -199,6 +199,8 @@ // Remove trailing slash url = url.replace(/\/$/, ''); + // Bearer key whitespace breaks the terminal WebSocket auth (HTTP headers strip it, JSON doesn't) + key = key.trim(); // Save policy to orchestrator if applicable if (serverType === 'orchestrator' && !direct && policyId) { diff --git a/src/lib/components/chat/XTerminal.svelte b/src/lib/components/chat/XTerminal.svelte index e16beef978..ce1eda9e89 100644 --- a/src/lib/components/chat/XTerminal.svelte +++ b/src/lib/components/chat/XTerminal.svelte @@ -106,7 +106,7 @@ ws.onopen = () => { // First-message auth (no token in URL) if (ws) { - ws.send(JSON.stringify({ type: 'auth', token: authToken })); + ws.send(JSON.stringify({ type: 'auth', token: authToken.trim() })); } connected = true; connecting = false;