You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[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
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
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.
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.
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.
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.
Activity
juliusmarminge commentedon Oct 3, 2026
Note
Grok responding on behalf of Julius.
Triage
Thanks @Vantrongs for the clear write-up and the screenshot.
Confirmed on main (
ce90eec). The missing-lsofpath 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, theProcessSpawnErroris logged at debug level and discovery falls back toprobeCommonPorts()(PortScanner.ts).That probe only tries 16 ports:
3000,3001,3333,4173,4200,4321,5000,5173,5174,5175,5500,8000,8080,8081,8888, and9000.5173is on the list and8765isn't, which matches your screenshot. Anything it finds comes back withpid: null,processName: null, andterminal: null, so terminal ownership never attaches. The preview doesn't mention that discovery is limited, and while a preview is open the scan retrieslsofevery 3 seconds.The app doesn't bundle
lsof, so any desktop install where it isn't on the server'sPATH(NixOS by default) always takes this path.Workaround for now: install
lsofsomewhere the server process can see it, or type the URL into the preview bar.Likely fix area
Your
/proc/net/tcp+/proc/net/tcp6idea (listeners in state0A, 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:lsofwhen it's available, since macOS has no/proc/net/tcp.lsofis missing, rather than failing a spawn every 3 seconds.A maintainer will decide on the fix direction.
stantheman0128 commentedon Oct 3, 2026
The triage note matches the code: keep
lsofwhen it exists, and on Linux read/proc/net/tcpand/proc/net/tcp6when it does not. A bounded fd walk can still list a port when its pid cannot be read, and a missinglsofshould 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.