[GH-ISSUE #169] [connection closed] on terminal in open webui after update to latest #100

Closed
opened 2026-10-18 21:10:44 +00:00 by bsakaguchi · 10 comments
Owner

Originally created by @riegera2412 on GitHub (Sep 7, 2026).
Original GitHub issue: https://github.com/open-webui/open-terminal/issues/169

Hey,
as the title says, after updating from v0.12.3 to v0.12.4 (latest) just yesterday I get [connection closed] in the terminal window inside open webui. Going back to v0.12.3 fixed the issue for now.

Not sure what the error exactly is caused by. The docker logs of both containers look fine and the llm's I use can still work in opern-terminal. I have seen the older issues regarding this. Since those were fixed, I assume this might be a new issue.

I am not sure what info you need from me to fix this, so I leave this issue as is for now.

Originally created by @riegera2412 on GitHub (Sep 7, 2026). Original GitHub issue: https://github.com/open-webui/open-terminal/issues/169 Hey, as the title says, after updating from v0.12.3 to v0.12.4 (latest) just yesterday I get [connection closed] in the terminal window inside open webui. Going back to v0.12.3 fixed the issue for now. Not sure what the error exactly is caused by. The docker logs of both containers look fine and the llm's I use can still work in opern-terminal. I have seen the older issues regarding this. Since those were fixed, I assume this might be a new issue. I am not sure what info you need from me to fix this, so I leave this issue as is for now.
Author
Owner

@nderevj commented on GitHub (Sep 7, 2026):

I'm seeing the same issue. As @riegera2412 mentioned, rolling back to v0.12.3 fixed it.

<!-- gh-comment-id:5573367941 --> @nderevj commented on GitHub (Sep 7, 2026): I'm seeing the same issue. As @riegera2412 mentioned, rolling back to v0.12.3 fixed it.
Author
Owner

@kev-cs commented on GitHub (Sep 7, 2026):

Hi, I'm a recently new user of open-webui. I was confused thinking something was wrong on my end but using v0.12.3 fixes it. Thank you @riegera2412 !

I can also confirm my llm still can use open-terminal. I'm using docker compose for all of my setup and strangely I'm not seeing any error logs (only success logs) about this anywhere including open-webui, open-terminal and even in my browser's devtools on the webapp.

<!-- gh-comment-id:5576139742 --> @kev-cs commented on GitHub (Sep 7, 2026): Hi, I'm a recently new user of open-webui. I was confused thinking something was wrong on my end but using v0.12.3 fixes it. Thank you @riegera2412 ! I can also confirm my llm still can use open-terminal. I'm using docker compose for all of my setup and strangely I'm not seeing any error logs (only success logs) about this anywhere including open-webui, open-terminal and even in my browser's devtools on the webapp.
Author
Owner

@definity commented on GitHub (Sep 8, 2026):

Warning ---> Claude figured this out with some prompting on my side <---- maybe obvious but I was curious to find out why reverting to v0.12.3 resolved the issue.

The WS auth token succeeds, then the server immediately closes with code 4004 "Session not found".

That comes from the new ownership check added here: github.com/open-webui/open-terminal@f0edc9ecc5 (diff-main.py) (ws_terminal in open_terminal/main.py):

if (
    session["user_id"] != ws.headers.get("x-user-id", "")
    or session["chat_id"] != ws.headers.get("x-session-id", payload.get("chat_id", ""))
):
    await ws.close(code=4004, reason="Session not found")

Open WebUI sends X-User-Id on every REST call (POST /api/terminals, /files/*, etc.) but on the websocket upgrade it only puts user_id in the URL query string — no X-User-Id header. This check only reads the header, with no query-param fallback (unlike the chat_id check right next to it, which does fall back to the payload). So the header comparison is always "" != "<real-user-id>" and the socket gets closed every time.

Matches the changelog's own note that this 0.12.4 feature "Requires Open WebUI 0.11.4" — which hasn't been published yet (latest is 0.11.3). Workaround: pin back to ghcr.io/open-webui/open-terminal:0.12.3 until 0.11.4 ships.

Packet capture (tcpdump on the open-terminal host, decoded with tshark), same session, in order:

# 1. Open WebUI creates the session over plain HTTP — note X-User-Id IS present here
POST /api/terminals HTTP/1.1
Host: <host>:8000
X-User-Id: 68d001ba-f560-4944-9d1a-f6660fe3f47a
Authorization: Bearer <redacted>
User-Agent: Python/3.11 aiohttp/3.13.5
Content-Length: 0

  -> 200 OK  {"id":"879edd14", ...}

# 2. Open WebUI opens the terminal websocket — user_id is only in the query string,
#    X-User-Id header is ABSENT
GET /api/terminals/879edd14?user_id=68d001ba-f560-4944-9d1a-f6660fe3f47a HTTP/1.1
Host: <host>:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: <redacted>
User-Agent: Python/3.11 aiohttp/3.13.5

  -> HTTP/1.1 101 Switching Protocols

# 3. Client sends first-message auth (correct token, ws.accept() already happened)
WS TEXT (client -> server):
  {"type": "auth", "token": "<redacted>"}

# 4. Server validates the token fine, then evaluates the ownership check and closes
WS CLOSE (server -> client):
  Opcode: 8 (Connection Close)
  Status code: 4004 (private use)
  Reason: "Session not found"

Step 2 seems to make it clear: compare its header list against step 1's — X-User-Id never made it onto the websocket handshake. That's exactly the input ws.headers.get("x-user-id", "") in the commit above sees, so it evaluates to "" != "68d001ba-...", and step 4 is that await ws.close(code=4004, reason="Session not found") line firing.

<!-- gh-comment-id:5585092322 --> @definity commented on GitHub (Sep 8, 2026): Warning ---> Claude figured this out with some prompting on my side <---- maybe obvious but I was curious to find out why reverting to v0.12.3 resolved the issue. The WS auth token succeeds, then the server immediately closes with code 4004 "Session not found". That comes from the new ownership check added here: https://github.com/open-webui/open-terminal/commit/f0edc9ecc53329ab7cfef78711b4b478e251d6c2#diff-main.py (`ws_terminal` in `open_terminal/main.py`): ```python if ( session["user_id"] != ws.headers.get("x-user-id", "") or session["chat_id"] != ws.headers.get("x-session-id", payload.get("chat_id", "")) ): await ws.close(code=4004, reason="Session not found") ``` Open WebUI sends `X-User-Id` on every REST call (`POST /api/terminals`, `/files/*`, etc.) but on the websocket upgrade it only puts `user_id` in the URL query string — no `X-User-Id` header. This check only reads the header, with no query-param fallback (unlike the `chat_id` check right next to it, which does fall back to the payload). So the header comparison is always `"" != "<real-user-id>"` and the socket gets closed every time. Matches the changelog's own note that this 0.12.4 feature "Requires Open WebUI 0.11.4" — which hasn't been published yet (latest is 0.11.3). Workaround: pin back to `ghcr.io/open-webui/open-terminal:0.12.3` until 0.11.4 ships. **Packet capture** (tcpdump on the open-terminal host, decoded with tshark), same session, in order: ``` # 1. Open WebUI creates the session over plain HTTP — note X-User-Id IS present here POST /api/terminals HTTP/1.1 Host: <host>:8000 X-User-Id: 68d001ba-f560-4944-9d1a-f6660fe3f47a Authorization: Bearer <redacted> User-Agent: Python/3.11 aiohttp/3.13.5 Content-Length: 0 -> 200 OK {"id":"879edd14", ...} # 2. Open WebUI opens the terminal websocket — user_id is only in the query string, # X-User-Id header is ABSENT GET /api/terminals/879edd14?user_id=68d001ba-f560-4944-9d1a-f6660fe3f47a HTTP/1.1 Host: <host>:8000 Upgrade: websocket Connection: Upgrade Sec-WebSocket-Version: 13 Sec-WebSocket-Key: <redacted> User-Agent: Python/3.11 aiohttp/3.13.5 -> HTTP/1.1 101 Switching Protocols # 3. Client sends first-message auth (correct token, ws.accept() already happened) WS TEXT (client -> server): {"type": "auth", "token": "<redacted>"} # 4. Server validates the token fine, then evaluates the ownership check and closes WS CLOSE (server -> client): Opcode: 8 (Connection Close) Status code: 4004 (private use) Reason: "Session not found" ``` Step 2 seems to make it clear: compare its header list against step 1's — `X-User-Id` never made it onto the websocket handshake. That's exactly the input `ws.headers.get("x-user-id", "")` in the commit above sees, so it evaluates to `"" != "68d001ba-..."`, and step 4 is that `await ws.close(code=4004, reason="Session not found")` line firing.
Author
Owner

@definity commented on GitHub (Sep 8, 2026):

Follow-up: re-ran the same capture against 0.12.3 to show how the response is different.

# 0.12.3 response
WS BINARY (server -> client): 90 bytes of PTY output — session works

# 0.12.4 response
WS CLOSE (server -> client): code 4004, reason "Session not found"

It's the new ownership check in f0edc9e comparing ws.headers.get("x-user-id", "") (always empty, since this header was never sent on the WS handshake to begin with) against session["user_id"]. 0.12.3 didn't have that check.

<!-- gh-comment-id:5585205662 --> @definity commented on GitHub (Sep 8, 2026): Follow-up: re-ran the same capture against 0.12.3 to show how the response is different. ``` # 0.12.3 response WS BINARY (server -> client): 90 bytes of PTY output — session works # 0.12.4 response WS CLOSE (server -> client): code 4004, reason "Session not found" ``` It's the new ownership check in f0edc9e comparing `ws.headers.get("x-user-id", "")` (always empty, since this header was never sent on the WS handshake to begin with) against `session["user_id"]`. 0.12.3 didn't have that check.
Author
Owner

@akehir commented on GitHub (Sep 16, 2026):

I can confirm; I observed the same issue on main; reverting f0edc9e fixes the issue.

<!-- gh-comment-id:5705755849 --> @akehir commented on GitHub (Sep 16, 2026): I can confirm; I observed the same issue on main; reverting [f0edc9e](https://github.com/open-webui/open-terminal/commit/f0edc9ecc53329ab7cfef78711b4b478e251d6c2) fixes the issue.
Author
Owner

@dMwJr commented on GitHub (Oct 14, 2026):

this is still an issue

<!-- gh-comment-id:6178929318 --> @dMwJr commented on GitHub (Oct 14, 2026): this is still an issue
Author
Owner

@definity commented on GitHub (Oct 15, 2026):

It's not an issue for me on the latest version of open webui v0.11.4 and v0.12.x

<!-- gh-comment-id:6200277259 --> @definity commented on GitHub (Oct 15, 2026): It's not an issue for me on the latest version of open webui v0.11.4 and v0.12.x
Author
Owner

@closesim commented on GitHub (Oct 15, 2026):

With Open WebUI v0.12.2 and Open Terminal v0.14.0, this is no longer an issue, as it was quickly fixed in a later release.

<!-- gh-comment-id:6201032412 --> @closesim commented on GitHub (Oct 15, 2026): With Open WebUI v0.12.2 and Open Terminal v0.14.0, this is no longer an issue, as it was quickly fixed in a later release.
Author
Owner

@dMwJr commented on GitHub (Oct 16, 2026):

8. It's not an issue for me on the latest version of open webui v0.11.4 and v0.12.x

That's not the latest versions of either of those apps

9. With Open WebUI v0.12.2 and Open Terminal v0.14.0, this is no longer an issue, as it was quickly fixed in a later release.

Not for me, I'm experiencing this exact issue, latest openwebui, latest open-terminals, and latest terminals. What logs could I look into here to provide more diagnostic information?

<!-- gh-comment-id:6205244474 --> @dMwJr commented on GitHub (Oct 16, 2026): > 8\. It's not an issue for me on the latest version of open webui v0.11.4 and v0.12.x That's not the latest versions of either of those apps > 9\. With Open WebUI v0.12.2 and Open Terminal v0.14.0, this is no longer an issue, as it was quickly fixed in a later release. Not for me, I'm experiencing this exact issue, latest openwebui, latest open-terminals, and latest terminals. What logs could I look into here to provide more diagnostic information?
Author
Owner

@Classic298 commented on GitHub (Oct 16, 2026):

Fixed. Open WebUI 0.11.4 and newer work with Open Terminal 0.12.4 and newer. The reports from early September were on Open WebUI 0.11.3.

I tested all setups and it works on these versions just fine. If you still hit it open a new issue, happy to triage, but this has been fixed for a while now

<!-- gh-comment-id:6210969103 --> @Classic298 commented on GitHub (Oct 16, 2026): Fixed. Open WebUI 0.11.4 and newer work with Open Terminal 0.12.4 and newer. The reports from early September were on Open WebUI 0.11.3. I tested all setups and it works on these versions just fine. If you still hit it open a new issue, happy to triage, but this has been fixed for a while now
Sign in to join this conversation.
No labels
bug
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
open-webui/open-terminal#100
No description provided.