can1357/oh-my-pi · error
LSP server ${config.command} failed to initialize recently:
Error message
LSP server ${config.command} failed to initialize recently: ${recentFailure.message} What it means
The client tracks deterministic initialization failures per server key with a backoff window (INIT_FAILURE_BACKOFF_MS). If the server failed to initialize recently, the library refuses to respawn it immediately — respawning a broken server on every tool call wastes the full init timeout each time — and throws with the original failure message.
Source
Thrown at packages/coding-agent/src/lsp/client.ts:992
}
const clientAfterReload = clients.get(key);
if (clientAfterReload && !invalidatedClientKeys.has(key)) {
clientAfterReload.lastActivity = Date.now();
return clientAfterReload;
}
const lockAfterReload = clientLocks.get(key);
if (lockAfterReload) return lockAfterReload.promise;
if (invalidatedClientKeys.has(key)) {
throw new Error(`LSP configuration was superseded during reload: ${config.command}`);
}
}
// Fail fast on a recent deterministic init failure instead of re-spawning
// a broken server (and paying its full init wait) on every call.
const recentFailure = initFailures.get(key);
if (recentFailure) {
if (Date.now() - recentFailure.at < INIT_FAILURE_BACKOFF_MS) {
throw new Error(`LSP server ${config.command} failed to initialize recently: ${recentFailure.message}`);
}
initFailures.delete(key);
}
// Create new client with lock
const lockToken = Symbol();
const clientPromise = (async () => {
const baseCommand = config.resolvedCommand ?? config.command;
const baseArgs = config.args ?? [];
// Wrap with lspmux if available and supported
const { command, args, env } = isLspmuxSupported(baseCommand)
? await getLspmuxCommand(baseCommand, baseArgs)
: { command: baseCommand, args: baseArgs };
// Prefer the broker-shared server unless an external lspmux wrapper is
// already multiplexing this command. Any shared-path failure falls back
// to a private spawn so LSP never regresses on broker trouble.View on GitHub (pinned to 9690622007)
Solutions
- Fix the root cause reported in the message (install the server binary, fix the project)
- Wait out the backoff window (INIT_FAILURE_BACKOFF_MS) and retry
- Explicitly reset/reload LSP config to clear the failure cache
Example fix
// before: immediate retry loop against dead server
for (;;) await lspDiagnostics(file);
// after: back off and surface root cause
try { await lspDiagnostics(file); }
catch (e) { logger.warn(e.message); await Bun.sleep(BACKOFF_MS); } Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the server command is runnable before invoking LSP
const bin = $which(config.command);
if (!bin) throw new Error(`LSP command not on PATH: ${config.command}`); Try / catch
try {
const client = await getConfigOrCreate(config, cwd);
} catch (err) {
if (err.message.startsWith(`LSP server ${config.command} failed to initialize recently`)) {
// Surface the root cause to the user instead of hammering the dead server
logger.warn('LSP init failing repeatedly', { command: config.command, cause: err.message });
}
throw err;
} Prevention
- Install/verify the language server binary and its runtime before use
- Fix the underlying init failure reported in the message — the backoff hides it, not solves it
- Respect the backoff window rather than retrying in a tight loop
When it happens
Trigger: An earlier attempt to start the LSP server failed (crash, bad command, timeout), and a new LSP-dependent call arrives within the backoff window.
Common situations: LSP binary not installed or not on PATH; server crashes on startup due to bad project state; server requires a newer runtime version than installed.
Related errors
- Failed to initialize LSP: no response
- LSP configuration was superseded during initialization: ${co
- No active model on agent
- No model configured
- No session - local:// unavailable
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1cde13b3d0906a49.
Report an issue: GitHub.