Skip to content

[Web] Infinite Authentication Loop when opening Terminal in v1.2.25 #17376

Closed as not planned

Description

@boyu8266

Description

After configuring a username and password, attempting to open the Terminal in OpenCode Web results in a continuous authentication prompt. Even after entering the correct credentials, the login dialog reappears immediately, preventing access to the terminal interface.

InShot_20260313_223240715.mp4

Plugins

No response

OpenCode version

v1.2.25

Steps to reproduce

  1. [CLI] OPENCODE_SERVER_USERNAME=username OPENCODE_SERVER_PASSWORD=yourpassword opencode web
  2. [Browser] localhost:4096
  3. Enter username/password
  4. Click terminal icon

Screenshot and/or share link

No response

Operating System

No response

Terminal

No response

Activity

  1. github-actions commented on Mar 13, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. maddestructor commented on Mar 13, 2026

    @maddestructor

    My colleague and I are having the same issue on our side when using basic auth on an opencode server.

  3. Cellule commented on Mar 13, 2026

    @Cellule

    I've narrowed it down to something happening when the web app tries to open a connection to the terminal

    const url = new URL(sdk.url + `/pty/${id}/connect`)
    url.searchParams.set("directory", sdk.directory)
    url.searchParams.set("cursor", String(seek))
    url.protocol = url.protocol === "https:" ? "wss:" : "ws:"
    url.username = server.current?.http.username ?? "opencode"
    url.password = server.current?.http.password ?? ""
    const socket = new WebSocket(url)
    socket.binaryType = "arraybuffer"
    ws = socket

    Basically, when the websocket tries to open, it does not contain the Basic Authorization header, causing a 401 which then causes the browser to clear its existing Basic Auth from memory and request a new one.
    Repro Steps

    • open opencode in a private/incognito window
    • type in username password
    • open any project
    • open the terminal (this causes the 401 loop)

    Workaround, set the username password in the server settings (on top of the basic auth request). I honestly didn't even know this was a thing...
    Image

    I'll ask OpenCode to post the findings on my research here in a moment

  4. Cellule commented on Mar 13, 2026

    @Cellule

    Root Cause Analysis

    The infinite authentication loop is caused by the terminal's WebSocket connection explicitly sending wrong credentials, which poisons the browser's HTTP Basic Auth cache.

    The Bug

    When the web app opens a terminal, terminal.tsx constructs a WebSocket URL with explicit credentials:

    // packages/app/src/components/terminal.tsx (current)
    url.username = server.current?.http.username ?? "opencode"
    url.password = server.current?.http.password ?? ""

    For web browser access (not desktop), server.current.http has no stored username or password — the user authenticated via the browser's native Basic Auth dialog, and those credentials are never captured by the app. So this evaluates to:

    • url.username = "opencode"
    • url.password = "" (empty string)

    The WebSocket URL becomes ws://opencode:@host:port/pty/.../connect, which explicitly tells the browser to send Authorization: Basic b3BlbmNvZGU6 (base64 of opencode:) — overriding the browser's cached (correct) Basic Auth credentials.

    The server rejects this (empty password ≠ real password) with 401 Unauthorized. This 401 on the WebSocket handshake poisons the browser's auth cache for the entire origin, causing all subsequent requests to fail and triggering the infinite re-authentication loop.

    Why regular HTTP requests work

    The PUT request to create the PTY (PUT /pty/{id}) works fine because it uses the SDK's fetch(), which inherits the browser's cached Basic Auth credentials automatically. Only the WebSocket is broken because it explicitly overrides credentials via the URL.

    Regression History

    PR #13813 (1bb857417, Feb 18) introduced the latent bug by removing a conditional guard:

    -// BEFORE: Only set WebSocket creds when desktop app provides them
    -if (window.__OPENCODE__?.serverPassword) {
    -  url.username = "opencode"
    -  url.password = window.__OPENCODE__?.serverPassword
    -}
    
    +// AFTER: Always sets creds unconditionally — empty for web browser
    +url.username = server.current?.http.username ?? ""
    +url.password = server.current?.http.password ?? ""

    Before this change, the web browser path left the WebSocket URL without explicit credentials, so the browser's auth cache handled authentication correctly.

    PR #17061 (c9c0318e0, Mar 12) then turned this latent bug into an active one by changing the username fallback from "" to "opencode". With both username and password as empty strings, some browsers treat the URL as having no credentials and still use the auth cache. With username="opencode" and password="", the browser now explicitly sends wrong credentials, guaranteeing the 401.

    Suggested Fix

    Only set explicit WebSocket credentials when the server connection actually has stored credentials (i.e., the user entered them in the app's "Add Server" dialog, not via the browser's native auth prompt):

    if (server.current?.http.password) {
      url.username = server.current.http.username ?? "opencode"
      url.password = server.current.http.password
    }

    This lets the browser's Basic Auth cache handle WebSocket authentication transparently for web browser users — the same way it already works for all regular HTTP requests (PUT, GET, SSE, etc.).

  5. Cellule commented on Mar 14, 2026

    @Cellule

    I haven't been able to test the fix locally because my local setup doesn't trigger the basic auth request (the browser doesn't ask for credentials when the url of the page doesn't match the url of the server)
    If someone can help me set it up properly to test it I could confirm and open a PR.
    Otherwise, if someone is setup to test it and wants to open the PR go right ahead, I just hope my investigation helps :)

  6. boyu8266 commented on Mar 14, 2026

    @boyu8266
    Author

    Workaround, set the username password in the server settings (on top of the basic auth request). I honestly didn't even know this was a thing... Image

    I'll ask OpenCode to post the findings on my research here in a moment

    Thank you!
    The workaround worked perfectly for me.

    The ability to use the terminal on mobile starting from version 1.2.25 is also a huge help for my workflow. 👍

  7. Cellule commented on Mar 17, 2026

    @Cellule

    I was able to test the fix using content overrides in the devtools.
    I'll open a PR soon

  8. crd2333 commented on Mar 27, 2026

    @crd2333

    same problem, and not fixed yet in v1.3.3. Hope for quick merge

  9. waitle commented on Mar 30, 2026

    @waitle

    Still not fixed in v1.3.7.
    This is very critical in web based usage...
    Infinite http auth request makes impossible to use webUI.

  10. hadestructhor commented on Mar 31, 2026

    @hadestructhor

    Any idea when this will be fixed ? I really love opencode, and I was thinking I could use the web served version on my vps just like how @adamdotdevin said in a podcast I watched the other day.

  11. crd2333 commented on Apr 1, 2026

    @crd2333

    A temporary solution before this is fixed (at least works for me), is that set the user_name as opencode but set the password personal. And when you use the web app, never touch the terminal button (try any other terminals instead, like ssh).

  12. hadestructhor commented on Apr 1, 2026

    @hadestructhor

    A temporary solution before this is fixed (at least works for me), is that set the user_name as opencode but set the password personal. And when you use the web app, never touch the terminal button (try any other terminals instead, like ssh).

    This is what I'm doing currently, with termux, but I'd like to only use one app instead of switching back and forth. Other than that, what an amazing app opencode is

  13. richard-fairthorne commented on Apr 4, 2026

    @richard-fairthorne

    I experience this problem in 1.3.12 on Linux under different circumstances, which may help narrow down the cause.

    I do not have authentication configured for opencode. Instead, my opencode instance is behind an NGINX proxy which has authentication. Opening the terminal results in an authentication loop.

  14. adrianord commented on Apr 11, 2026

    @adrianord

    On OpenCode version 1.4.3, this appears to be fixed. I can have the terminal open without being in an infinite auth loop

  15. Cellule commented on Apr 11, 2026

    @Cellule

    Fixed by #19923

  16. thejacer commented on Apr 27, 2026

    @thejacer

    This just happened to me. Was running 1.2.x and accidentally clicked terminal, got infinite auth loop. I tried terminating opencode on the server and when it came back up it was still looping. Then upgraded to 1.14.28, still looping. Tried starting it with no password, still looping.

  17. removed
    bugSomething isn't working
    webRelates to opencode on web / desktop
    on May 3, 2026
  18. github-actions commented on Jul 3, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions