Skip to content

[Bug]: On Linux without lsof, preview port discovery checks only 16 common ports, so a dev server on any other port never shows up #15244

Closed

Description

@Vantrongs

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. On Linux without lsof (NixOS doesn't install it by default), start the same server on a port outside the common list and on a common one: python3 -m http.server 8765 and python3 -m http.server 5173.
  2. Open a new preview tab and look at the local servers it offers.

Expected behavior

Both servers are offered, as they are when lsof is installed.

Actual behavior

Only 5173 is offered. On Linux and macOS, PortScanner lists listeners only through lsof -iTCP -sTCP:LISTEN. When lsof can't be spawned, it logs at debug level and falls back to probeCommonPorts, which checks the 16 ports in COMMON_DEV_PORTS and returns them with pid: null and terminal: null. So a server on any other port is never discovered, and even a server on a common port loses its terminal ownership. Nothing in the UI says discovery is limited, and the scan retries lsof every 3 seconds.

A possible fix: on Linux, read listeners from /proc/net/tcp and /proc/net/tcp6 and map their socket inodes to PIDs through /proc/<pid>/fd, which needs no extra binary.

Impact

Minor bug or occasional failure

Version or commit

0.0.46-nightly.20261003.2623 (fed41fa)

Environment

Desktop app on Linux (NixOS, Wayland, niri); Claude Code 2.1.288

Logs or stack traces

No response

Screenshots, recordings, or supporting files

A new preview tab with servers on 8765 and 5173: "Local servers" lists only 5173

A new preview tab with servers on 8765 and 5173: "Local servers" lists only 5173

Workaround

No response

Activity

  1. added
    bugSomething is broken or behaving incorrectly.
    needs-triageIssue needs maintainer review and initial categorization.
    on Oct 3, 2026
  2. juliusmarminge commented on Oct 3, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Triage

    Thanks @Vantrongs for the clear write-up and the screenshot.

    Confirmed on main (ce90eec). The missing-lsof path does what it was written to do, but it's too limited to serve as normal Linux discovery.

    On macOS and Linux, preview discovery runs lsof -iTCP -sTCP:LISTEN -P -n -F pcn. If that can't be spawned, the ProcessSpawnError is logged at debug level and discovery falls back to probeCommonPorts() (PortScanner.ts).

    That probe only tries 16 ports: 3000, 3001, 3333, 4173, 4200, 4321, 5000, 5173, 5174, 5175, 5500, 8000, 8080, 8081, 8888, and 9000. 5173 is on the list and 8765 isn't, which matches your screenshot. Anything it finds comes back with pid: null, processName: null, and terminal: null, so terminal ownership never attaches. The preview doesn't mention that discovery is limited, and while a preview is open the scan retries lsof every 3 seconds.

    The app doesn't bundle lsof, so any desktop install where it isn't on the server's PATH (NixOS by default) always takes this path.

    Workaround for now: install lsof somewhere the server process can see it, or type the URL into the preview bar.

    Likely fix area

    Your /proc/net/tcp + /proc/net/tcp6 idea (listeners in state 0A, socket inodes mapped to PIDs through /proc/<pid>/fd) fits well as the Linux fallback. It needs no extra binary, and having a PID keeps terminal ownership. Some details worth keeping in mind:

    • Keep using lsof when it's available, since macOS has no /proc/net/tcp.
    • Remember that lsof is missing, rather than failing a spawn every 3 seconds.
    • Keep the fd walk bounded on each tick, and still list a port when its fds can't be read.

    A maintainer will decide on the fix direction.

  3. added
    via-triageFiled through npx t3 triage
    and removed
    needs-triageIssue needs maintainer review and initial categorization.
    on Oct 3, 2026
  4. stantheman0128 commented on Oct 3, 2026

    @stantheman0128

    The triage note matches the code: keep lsof when it exists, and on Linux read /proc/net/tcp and /proc/net/tcp6 when it does not. A bounded fd walk can still list a port when its pid cannot be read, and a missing lsof should be remembered instead of respawned every 3 seconds.

    I can send a PR for that fallback only. I will wait until a maintainer picks this direction.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions