can1357/oh-my-pi · error

LSP mux already listening on ${endpoint}

Error message

LSP mux already listening on ${endpoint}

What it means

The LSP mux Unix-domain socket server throws this when starting a listener finds an existing socket file at the endpoint that still answers a liveness probe. It prevents a second mux from silently hijacking a socket owned by a live daemon, which would break all connected clients.

Source

Thrown at packages/coding-agent/src/lsp/mux/server.ts:252

			await promise;
		}
		if (process.platform !== "win32" && this.#endpoint) {
			try {
				await fs.unlink(this.#endpoint);
			} catch {
				// The socket may already have been removed by process cleanup.
			}
		}
	}

	async #clearStaleSocket(endpoint: string): Promise<void> {
		try {
			await fs.stat(endpoint);
		} catch {
			return;
		}
		const alive = await this.#probe(endpoint);
		if (alive) throw new Error(`LSP mux already listening on ${endpoint}`);
		try {
			await fs.unlink(endpoint);
		} catch (error) {
			logger.warn("Failed to remove stale LSP mux socket", { endpoint, error: String(error) });
			throw error;
		}
	}

	async #probe(endpoint: string): Promise<boolean> {
		const { promise, resolve } = Promise.withResolvers<boolean>();
		const socket = net.createConnection(endpoint);
		socket.once("connect", () => {
			socket.destroy();
			resolve(true);
		});
		socket.once("error", () => {
			socket.destroy();
			resolve(false);

View on GitHub (pinned to 9690622007)

Solutions

  1. Do nothing — a healthy mux is already running on this endpoint; connect to it instead of starting a new server.
  2. Stop the existing daemon (`omp lsp stop` or kill the mux process) before restarting.
  3. Delete or change the mux socket endpoint configuration if the running daemon is unwanted.
  4. If the socket is actually stale (probe race), remove it manually and retry.

Example fix

// before
await new LspMuxServer().listen(endpoint);
// after
if (await isLspMuxAlive(endpoint)) return; // reuse existing daemon
await new LspMuxServer().listen(endpoint);
Defensive patterns

Strategy: try-catch

Validate before calling

import * as fs from "node:fs/promises";
async function muxSocketInUse(endpoint: string) {
  try { await fs.stat(endpoint); return true; } catch { return false; }
}
// skip starting a mux if muxSocketInUse(endpoint)

Try / catch

try {
  await server.listen(endpoint);
} catch (err) {
  if (err instanceof Error && err.message.includes("already listening")) {
    // reuse the running daemon; continue
  } else throw err;
}

Prevention

When it happens

Trigger: Calling listen() on an LspMuxServer when #clearStaleSocket finds the socket file exists and the #probe() ping succeeds, i.e. another live mux daemon is already bound to that endpoint.

Common situations: Launching a second `omp lsp mux` manually while a detached daemon is already running; stale environment pointing at another project's live mux; running two omp processes with the same mux endpoint configured.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/1fa1de9e04802e81. Report an issue: GitHub.