fix: show clear error when LS webview port is unreachable

Summary

Agentic Chat, Agentic Tabs, and other LS-hosted webviews would silently render a dead iframe (or hang with a generic "didn't initialize" timeout) when the Language Server's localhost port couldn't be reached — common in Remote-SSH, Dev Containers, and browser-based VS Code when the port isn't forwarded or is blocked by a firewall/VPN.

  • LsWebviewController now awaits its existing #isUrlAvailble() reachability check (previously fire-and-forget, only logged) before deciding what to render.
  • Shows a lightweight "Loading…" placeholder immediately, since the check can take up to 5s.
  • Only when the URL is genuinely unreachable does it render a clear, GitLab-branded error screen naming the specific port, instead of a dead iframe.
  • The message is environment-aware via vscode.env.uiKind: on the VS Code desktop app (including Remote-SSH/Dev Containers/WSL) it points at the Ports panel and tells users to actually try opening the listed port (a green "forwarded" dot doesn't guarantee the connection works) before checking firewall/VPN/antivirus settings. In browser-based VS Code (uiKind === Web), it explains that port-forwarding may not be supported at all in that environment and suggests the desktop app or filing a report.
  • LSDuoChatWebviewController skips its own redundant timeout wait when the base class already reported the URL unreachable, so the more specific message isn't overwritten.
  • Nothing is disabled preemptively based on remote/web detection alone — the port is often reachable in Remote-SSH/Dev Containers, so Agentic Chat/Tabs still attempt to load normally everywhere; the error only shows on genuine failure.

This does not restore Agentic Chat functionality in environments where the localhost port is structurally unreachable (e.g. plain browser-based VS Code Web without tunnel support) — see #2310 (closed) for the longer-term architectural fix (routing webview messaging over the existing LSP connection instead of a parallel HTTP/Socket.IO server) tracked separately.

  • #2310 (closed)
  • gitlab#604254 (customer-facing tracking issue, confirms the languageServerWebviews: false workaround doesn't help Agentic Chat)

Test plan

Remote-SSH / Dev Containers (tested)

  1. Open a Remote-SSH or Dev Container workspace with GitLab Duo enabled, and sign in.

  2. In the "GitLab Language Server" output channel, find the line [HttpServer]: server listening on http://127.0.0.1:<port> and note <port>.

  3. Before opening any Duo/Agentic panel this session, block that port to simulate an unreachable localhost service:

    sudo iptables -A OUTPUT -p tcp --dport <port> -d 127.0.0.1 -j REJECT
  4. Open GitLab Duo Agent Platform > Chat (Agentic Chat) or the Agentic Tabs panel for the first time this session.

  5. Confirm: a brief "Loading…" placeholder appears, followed within ~5s by a GitLab-branded error screen naming the blocked port and pointing at the Ports panel — not a blank panel, dead iframe, or generic "didn't initialize" message.

  6. Open the classic GitLab Duo Chat sidebar (gl.chatView) and confirm it still works normally (unaffected, since it doesn't depend on the LS-hosted webview path).

  7. Clean up: sudo iptables -D OUTPUT -p tcp --dport <port> -d 127.0.0.1 -j REJECT, then confirm Agentic Chat/Tabs load normally again after a fresh reload (no port blocked) — i.e. nothing is disabled just because the session is "remote."

Screenshot 2026-07-17 at 20.27.46.png

VS Code Web / browser-based (follow-up)

Tested with VS Code web interface in a coder.com instance.

  1. Open a Remote-SSH or Dev Container workspace with GitLab Duo enabled, and sign in.
  2. verify the 'Ports' tab does not exist, or if it does, there is no forwarded ports
  3. Open GitLab Duo Agent Platform > Chat (Agentic Chat) or the Agentic Tabs panel for the first time this session.
  4. Confirm: a brief "Loading…" placeholder appears, followed within ~5s by a GitLab-branded error screen naming the blocked port and describing the problem with browser based environments — not a blank panel, dead iframe, or generic "didn't initialize" message.

Screenshot 2026-07-20 at 08.48.42.png

  • Remote-SSH / Dev Container repro verified manually (blocked port -> clear error; unblocked port -> normal load)
  • VS Code Web / browser-based repro verified manually
  • Unit tests added/updated (ls_webview_controller.test.ts, duo_chat_controller.test.ts)
  • npm run package builds a working .vsix

🤖 Generated with Claude Code

Edited by James Casey

Merge request reports

Loading
Loading