mastra-ai/mastra · error

Failed to spawn LSP server

Error message

Failed to spawn LSP server

What it means

LSPClient.initialize() starts the language server by calling serverInfo.spawn(workspaceRoot). If spawn returns null/false (the server binary could not be launched), the client throws Error('Failed to spawn LSP server'). This is the wrapper thrown when the underlying spawn callback yields no ChildProcess at all.

Source

Thrown at mastracode/sdk/src/lsp/client.ts:31

  private process: ChildProcess | null = null;
  private serverInfo: LSPServerInfo;
  private workspaceRoot: string;
  private diagnostics: Map<string, Diagnostic[]> = new Map();
  private initializationOptions: any = null;

  constructor(serverInfo: LSPServerInfo, workspaceRoot: string) {
    this.serverInfo = serverInfo;
    this.workspaceRoot = workspaceRoot;
  }

  /**
   * Initialize the LSP connection
   */
  async initialize(): Promise<void> {
    const spawnResult = await this.serverInfo.spawn(this.workspaceRoot);

    if (!spawnResult) {
      throw new Error('Failed to spawn LSP server');
    }

    // Handle both ChildProcess and { process: ChildProcess, initialization? } formats
    let initializationOptions: any = undefined;
    if ('process' in spawnResult) {
      this.process = spawnResult.process;
      initializationOptions = spawnResult.initialization;
    } else {
      this.process = spawnResult;
    }

    if (!this.process.stdin || !this.process.stdout) {
      throw new Error('Failed to create LSP process with proper stdio');
    }

    const reader = new StreamMessageReader(this.process.stdout);
    const writer = new StreamMessageWriter(this.process.stdin);
    this.connection = createMessageConnection(reader, writer);

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Verify the LSP server binary is installed and resolvable: run its command manually (e.g. `typescript-language-server --version`).
  2. Check the LSPServerInfo spawn configuration — correct command, args, and optional executablePath override.
  3. Ensure PATH in the environment running the SDK includes the server's install location (nvm/asdf/volta shims, global npm bin).
  4. Wrap initialize() in try/catch and implement a fallback (degrade without LSP features) or surface install instructions.

Example fix

// before
await client.initialize(); // throws: gopls not on PATH
// after
if (!commandExists(serverInfo.command)) {
  throw new Error(`LSP server '${serverInfo.command}' not installed; install it first`);
}
await client.initialize();
Defensive patterns

Strategy: try-catch

Validate before calling

import { spawnSync } from 'node:child_process';
function commandExists(cmd: string): boolean {
  const r = spawnSync(cmd, ['--version'], { stdio: 'ignore' });
  return !r.error;
}
// call before initialize(): if (!commandExists(serverInfo.command)) promptInstall(serverInfo.command);

Try / catch

try {
  await client.initialize();
} catch (e) {
  if (e.message === 'Failed to spawn LSP server') {
    logger.warn(`LSP server '${serverInfo.command}' unavailable; continuing without language features`);
    return; // degrade gracefully
  }
  throw e;
}

Prevention

When it happens

Trigger: initialize() (called via restart or the cached initPromise) when the configured LSP server's spawn callback fails — server command not found on PATH, wrong executablePath, spawn error swallowed by the serverInfo implementation returning null.

Common situations: Language server binary not installed (e.g. typescript-language-server, gopls missing); server installed via a version manager not active in the CLI's environment; typo in server command config; Windows shell quirks where the command isn't resolvable.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/1ea0e659dffc83f5. Report an issue: GitHub.