can1357/oh-my-pi · error · Error
Port ${host}:${chosen} is already in use; cannot start remot
Error message
Port ${host}:${chosen} is already in use; cannot start remote debugger there. What it means
startRemoteDebugger/launch refuses to bind its remote-debugger server when the chosen port already accepts connections. It probes the port first because a plain bind error would be ambiguous and a success probe might connect to an unrelated service already listening there.
Source
Thrown at packages/coding-agent/src/debug/remote-debugger.ts:123
export async function startRemoteDebuggerServer(options: StartRemoteDebuggerOptions = {}): Promise<RemoteDebuggerInfo> {
if (active) return active;
starting ??= launch(options);
try {
return await starting;
} finally {
starting = null;
}
}
async function launch({ port, start = startRemoteDebugger }: StartRemoteDebuggerOptions): Promise<RemoteDebuggerInfo> {
const host = DEFAULT_HOST;
const chosen = port ?? (await reserveFreePort(host));
// Something already on this port? Refuse up front: otherwise Bun throws a
// real bind error and our success probe would connect to that unrelated
// service, marking a bogus endpoint as the debugger.
if (await tryConnect(host, chosen, PROBE_INTERVAL_MS)) {
throw new Error(`Port ${host}:${chosen} is already in use; cannot start remote debugger there.`);
}
let thrown: unknown;
try {
start(host, chosen);
} catch (err) {
// Bun's startRemoteDebugger throws a spurious bind error even on success,
// so defer the verdict to the loopback probe below.
thrown = err;
}
if (await waitForListening(host, chosen)) {
active = { host, port: chosen };
return active;
}
throw thrown instanceof Error ? thrown : new Error(`Remote debugger socket never came up on ${host}:${chosen}`);
}View on GitHub (pinned to 9690622007)
Solutions
- Omit the `port` argument so a free port is reserved automatically
- Find and stop the process occupying the port (e.g. `lsof -i :<port>` / `ss -ltnp`)
- Choose a different port in your configuration
- Retry after a delay if the conflict was transient (another instance shutting down)
Example fix
// before
const dbg = await startRemoteDebuggerServer({ host: '127.0.0.1', port: 9229 });
// after
const dbg = await startRemoteDebuggerServer({ host: '127.0.0.1' }); // picks a free port Defensive patterns
Strategy: validation
Validate before calling
import { tryConnect } from './remote-debugger';
if (await tryConnect(host, port, 100)) {
throw new SkipOperation(`port ${host}:${port} occupied`);
} Try / catch
try {
const dbg = await startRemoteDebuggerServer({ host, port });
} catch (err) {
if (err.message.includes('already in use')) {
dbg = await startRemoteDebuggerServer({ host }); // let it pick a free port
}
} Prevention
- Prefer auto port selection over fixed ports
- Clean up debugger servers on exit (SIGINT handlers)
- Use unique port ranges per developer/container
When it happens
Trigger: Calling launch/startRemoteDebuggerServer with an explicit `port` that another process is listening on, or when `reserveFreePort(host)` returned a port that got claimed between reservation and bind (TOCTOU), on the given host.
Common situations: Two omp/debugger instances started concurrently; a stale debugger server from a crashed previous run still holding the port; another dev service occupying the port; hardcoded port in config colliding across team members or containers.
Related errors
- Failed to start stats dashboard on ${hostname}:${port} after
- timed out: {command}
- V2 remote compaction failed (${response.status} ${response.s
- V2 compaction stream closed before response.completed
- Auth broker response failed schema validation
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/22e9c1992c367bac.
Report an issue: GitHub.