can1357/oh-my-pi · error

Failed to restart ${serverName}: server process did not exit

Error message

Failed to restart ${serverName}: server process did not exit after kill

What it means

reloadServer asks the shared LSP server process to shut down; if the process is still alive after shutdown/kill completes, restarting would leave two conflicting instances, so it throws. This indicates a wedged or unkillable server process.

Source

Thrown at packages/coding-agent/src/lsp/servers.ts:314

		const params = reloadConfigurationParams(client.config);
		await sendNotification(client, "workspace/didChangeConfiguration", params, signal);
		return `Reloaded ${serverName}`;
	} catch {
		throwIfAborted(signal);
		// The reload notification could not be delivered — the connection is
		// wedged or the process already died. Tear the client down (removing it
		// from the registry by identity and awaiting confirmed process exit) so
		// the next request cold-starts a fresh client. A kill that never confirms
		// exit is not a restart: surface the teardown failure truthfully.
		//
		// On a broker-shared link a per-session teardown only detaches this
		// process while the wedged server keeps serving everyone else — ask the
		// mux to kill the shared server first (best-effort; it also severs us).
		if (client.proc.sharedMux) {
			await sendNotification(client, MUX_RESTART_METHOD, undefined, AbortSignal.timeout(2_000)).catch(() => {});
		}
		if (!(await shutdownClientInstance(client))) {
			throw new Error(`Failed to restart ${serverName}: server process did not exit after kill`);
		}
		return `Restarted ${serverName}`;
	}
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Kill the server process manually (find its PID via ps/`omp lsp status`) and retry the reload.
  2. Increase any shutdown timeout available in the server config, or disable the problematic language server extension.
  3. Restart the whole LSP mux daemon to force-reclaim all shared server processes.
  4. Report/pin the wedged language server version — some servers (e.g. certain gopls/jdtls builds) hang on shutdown.

Example fix

// before
await lspTool.execute({ action: "reload", server: "typescript" });
// after
try {
  await lspTool.execute({ action: "reload", server: "typescript" });
} catch (e) {
  // kill wedged server out-of-band, then retry once
  await restartMuxDaemon();
  await lspTool.execute({ action: "reload", server: "typescript" });
}
Defensive patterns

Strategy: retry

Validate before calling

// before reloading, check the server responds
await lspTool.execute({ action: "status", server: serverName, timeout: 10 });

Try / catch

try {
  await lspTool.execute({ action: "reload", server: name });
} catch (err) {
  if (err instanceof Error && err.message.includes("did not exit after kill")) {
    forceKillServerProcess(name); // out-of-band kill
    await lspTool.execute({ action: "reload", server: name });
  } else throw err;
}

Prevention

When it happens

Trigger: Calling the LSP tool `reload` action (execute → reloadServer) when shutdownClientInstance() returns false — the server process ignored SIGTERM/kill and did not exit within the wait window; with shared-mux servers a best-effort MUX_RESTART notification is sent first (2s timeout) but the local kill still failed.

Common situations: A language server deadlocked in native extension code and ignoring signals; a server stuck in uninterruptible I/O; very slow shutdown exceeding the wait window on a large project.

Related errors


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