can1357/oh-my-pi · warning

LSP configuration was superseded during initialization: ${co

Error message

LSP configuration was superseded during initialization: ${config.command}

What it means

Just before publishing a successfully initialized client into the shared client map, the code re-checks the invalidated set. If a config reload invalidated this key while initialization was running, the ready client is discarded and an error thrown — publishing it would expose a client whose config no longer matches user intent.

Source

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

			}

			client.serverCapabilities = initResult.capabilities as LspClient["serverCapabilities"];

			// Finish the initialize handshake before publishing the client as ready.
			await sendNotification(client, "initialized", {}, signal);
			await sendNotification(
				client,
				"workspace/didChangeConfiguration",
				{ settings: config.settings ?? {} },
				signal,
			);

			client.status = "ready";
			// Publish only after init succeeds: pre-init clients are reachable
			// solely through clientLocks, so concurrent callers (warmup vs first
			// tool call) wait for init instead of using an unacknowledged client.
			if (invalidatedClientKeys.has(key)) {
				throw new Error(`LSP configuration was superseded during initialization: ${config.command}`);
			}
			clients.set(key, client);
			initFailures.delete(key);
			return client;
		} catch (err) {
			// Clean up on initialization failure
			client.status = "error";
			if (clients.get(key) === client) clients.delete(key);
			proc.kill();
			const message = err instanceof Error ? err.message : String(err);
			// Negative-cache deterministic failures. Timeouts under a
			// caller-shortened deadline (warmup/writethrough) and caller-signal
			// aborts are transient — the server may simply be slow or the user may
			// have cancelled, so a later call with a fresh deadline should retry.
			if (!signal?.aborted && !(initTimeoutMs !== undefined && message.includes("timed out"))) {
				initFailures.set(key, { at: Date.now(), message });
			}
			throw err;

View on GitHub (pinned to 9690622007)

Solutions

  1. Retry the LSP operation — the retry creates a client from current config
  2. Wait for config reloads to complete before triggering LSP-heavy operations
  3. Avoid rapid successive config edits that repeatedly invalidate in-flight clients
Defensive patterns

Strategy: retry

Validate before calling

// Avoid initiating LSP work while a config reload is pending
if (configReloadPending) await configReloadFinished;

Try / catch

try {
  const client = await getConfigOrCreate(config, cwd);
} catch (err) {
  if (String(err.message).includes('superseded during initialization')) {
    return getConfigOrCreate(config, cwd); // retry picks up new config
  }
  throw err;
}

Prevention

When it happens

Trigger: Client initialization takes a while (slow server); during that window the user/config system triggers an LSP reload that invalidates the key; when init finishes, the check fires and the fully initialized client is thrown away.

Common situations: Editing LSP server settings while a slow-starting server (e.g. jdtls, rust-analyzer on a big project) initializes; config file watcher firing during startup.

Related errors


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