Skip to content

fix: connect the terminal at the ssh-terminal plugin path - #2

Merged
LukeGus merged 1 commit into
Termix-SSH:mainfrom
brennanneoh:fix/terminal-websocket-path
Oct 5, 2026
Merged

LukeGus merged 1 commit into
Termix-SSH:mainfrom
brennanneoh:fix/terminal-websocket-path

Conversation

@brennanneoh

Copy link
Copy Markdown
Contributor

Overview

termix ssh can't open a terminal on a Termix 2.9 server. 2.9 moved the terminal into the ssh-terminal plugin and removed /ssh/websocket/, the path the CLI connects to, so every handshake fails. Behind Cloudflare the error is Could not open the terminal connection: Unexpected server response: 502.

  • Added: ...
  • Updated: WEBSOCKET_ENDPOINTS lists both terminal paths
  • Removed: ...
  • Fixed: termix ssh connects at /plugin-ws/ssh-terminal/terminal and falls back to /ssh/websocket/ for servers older than 2.9

Changes Made

  • src/terminal/ws-client.ts: TerminalSocket.open() tries /plugin-ws/ssh-terminal/terminal first, then /ssh/websocket/.
    • It falls back only when the server answers the upgrade with an ordinary HTTP response, such as a 400, 404 or 502 for a route that doesn't exist on that version.
    • A 401 or 403, a refused connection or a timeout would fail the same way at the other path, so these are reported immediately and not retried.
  • Auth failures on 2.9: with a missing or expired token, 2.9 accepts the upgrade and then closes the socket with 1008 Authentication required. Older servers refused the handshake with a 401. That close now shows the same "run termix login" hint, and any other close message includes the server's reason, e.g. The server closed the connection: Data access required.
  • TERMIX_TERMINAL_URL hints: these now say they apply to backends older than 2.9. On 2.9 the terminal is served from the main backend port.
  • No protocol change needed. I compared plugins/ssh-terminal/src/backend/terminal-socket.ts at release-2.9.1-tag with what the CLI sends, and nothing else differs:
    • connectToHost and its ConnectToHostData fields are the same.
    • The replies the CLI handles (connected, passphrase_required, sessionAttached, data, error, session_ended) are the same.
    • The plugin WebSocket route reads Authorization: Bearer through extractWebSocketToken, the header the CLI already sends.

Related Issues

Screenshots / Demos

Against a 2.9.1 server behind a Cloudflare Tunnel:

$ termix ssh 32 --command 'echo TERMIX_OK; uname -sr; whoami'    # 1.0.1
termix: Could not open the terminal connection: Unexpected server response: 502

$ node dist/index.js ssh 32 --command 'echo TERMIX_OK; uname -sr; whoami'    # this branch
...
TERMIX_OK
Linux 6.12.107+deb13-amd64
brennan
# exits 0

Tests: six new cases in test/ws-client.test.ts:

  • uses the plugin path
  • falls back on a pre-2.9 server
  • doesn't retry after a 401
  • reports a 502 when neither path answers
  • gives the login hint on a 1008 Authentication required close
  • includes the reason on any other close

The existing tests now run against the plugin path. npm test passes 165 of 165, and format, lint and type-check are clean.

What hasn't been tested:

  • Interactive termix ssh in a real TTY. The live test used --command, which goes through the same handshake and connectToHost flow.
  • The fallback against a live pre-2.9 server. It's only covered by the unit test.

npm run smoke fails one check, "tarball contains the built entry point". It fails the same way on unmodified main with npm 12.0.2: npm pack --json output has a different shape there. CI pins npm 11, so I left it alone.

Checklist

  • Code follows project style guidelines
  • Supports mobile and desktop UI/app (if applicable)
  • I have read Contributing.md
  • This is not a translation request. See docs

Termix 2.9 moved the terminal into the ssh-terminal plugin, served at
/plugin-ws/ssh-terminal/terminal, and removed /ssh/websocket/. Every
`termix ssh` against a 2.9 server failed its handshake, which surfaces as
"Unexpected server response: 502" behind Cloudflare.

Try the plugin path first and fall back to /ssh/websocket/ when the server
answers without upgrading, so servers older than 2.9 keep working. A
refused credential, a refused connection or a timeout is reported
straight away rather than retried.

2.9 also accepts the upgrade and then closes with 1008 for a missing or
expired token, where older servers answered 401, so that close now gets
the same `termix login` hint, and any other close carries the server's
reason.
@LukeGus
LukeGus merged commit e524d56 into Termix-SSH:main Oct 5, 2026
1 check passed
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.

[BUG] CLI 1.0.1 can't open terminals on a 2.9.x server: termix ssh fails with 502 because /ssh/websocket/ no longer exists

2 participants