can1357/oh-my-pi · error

Failed to stop LSP server(s) with superseded configuration:

Error message

Failed to stop LSP server(s) with superseded configuration: ${failed.map(client => client.config.command).join(", ")}

What it means

When LSP configuration changes, clients whose cwd matches but whose names are no longer in the fresh config set are considered stale and are shut down. If any shutdown fails (shutdownClientInstance returned false), the operation throws listing the server commands that could not be stopped, so callers don't silently leave zombie servers.

Source

Thrown at packages/coding-agent/src/lsp/client.ts:911

			}
		}
		await Promise.all(
			stalePending.map(async ([, pending]) => {
				try {
					await untilAborted(signal, pending.promise);
				} catch {
					throwIfAborted(signal);
				}
			}),
		);

		const stale = Array.from(clients.values()).filter(
			client => path.resolve(client.cwd) === resolvedCwd && !fresh.has(client.name),
		);
		const results = await Promise.all(stale.map(client => shutdownClientInstance(client)));
		const failed = stale.filter((_client, index) => results[index] !== true);
		if (failed.length > 0) {
			throw new Error(
				"Failed to stop LSP server(s) with superseded configuration: " +
					failed.map(client => client.config.command).join(", "),
			);
		}
		return stale.map(client => client.config.command);
	})();
	clientReloadBarriers.set(resolvedCwd, cleanup);
	void cleanup.then(
		() => {
			if (clientReloadBarriers.get(resolvedCwd) === cleanup) clientReloadBarriers.delete(resolvedCwd);
		},
		() => {},
	);
	return cleanup;
}

/** Allow an explicit user reload to retry a matching initialization failure immediately. */
export function clearInitializationFailure(config: ServerConfig, cwd: string): void {

View on GitHub (pinned to 9690622007)

Solutions

  1. Manually kill the listed server processes (the message names each command).
  2. Retry the config reload once the server responds; hung servers often recover or stay dead.
  3. Check server logs for why shutdown was refused.
  4. If a server reliably hangs on shutdown, disable or upgrade that specific LSP server binary.

Example fix

// before
await lspClientRegistry.applyConfig(freshConfig); // throws listing stale servers
// after
try {
  await lspClientRegistry.applyConfig(freshConfig);
} catch (e) {
  if (e.message.includes("superseded configuration")) {
    for (const cmd of e.message.split(": ")[1]?.split(", ") ?? []) await killCommand(cmd);
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before reloading, confirm the listed servers respond to a health ping
const healthy = await Promise.all(servers.map(s => pingLspServer(s).then(() => true).catch(() => false)));
if (healthy.some(h => !h)) logger.warn("some LSP servers are unresponsive; shutdown may fail");

Try / catch

try {
  await registry.applyConfig(freshConfig);
} catch (e) {
  if (e.message.includes("superseded configuration")) {
    const commands = e.message.split(": ").slice(1).join(": ").split(", ");
    logger.error("LSP shutdown failed; killing manually", { commands });
    await Promise.all(commands.map(cmd => killCommand(cmd)));
  } else throw e;
}

Prevention

When it happens

Trigger: Reloading/changing LSP config where a previously running server's shutdown request times out, the process ignores SIGTERM/kill, or the server already crashed in a wedged state.

Common situations: A hung language server (e.g. typescript-language-server busy), insufficient permissions to kill the child process, config edit that renames a server while its old instance is unresponsive.

Related errors


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