mastra-ai/mastra · error

Failed to create LSP process with proper stdio

Error message

Failed to create LSP process with proper stdio

What it means

After spawning, the LSP client requires the child process to expose both stdin and stdout for the JSON-RPC stream connection. If either stream is missing (null), initialize() throws 'Failed to create LSP process with proper stdio'. Without these streams, createMessageConnection cannot be built, so the client fails fast.

Source

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

   */
  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);

    // Handle connection errors (e.g., ERR_STREAM_DESTROYED during shutdown)
    this.connection.onError(error => {
      // Silently ignore stream destroyed errors during shutdown
      const errorObj = error?.[0] as any;
      if (errorObj?.code !== 'ERR_STREAM_DESTROYED') {
      }
    });

    // Set up diagnostic listener before starting connection

    this.connection.onNotification('textDocument/publishDiagnostics', (params: any) => {
      if (params.diagnostics && params.diagnostics.length > 0) {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Spawn the server with stdio configured to pipe stdin/stdout (e.g. stdio: ['pipe', 'pipe', 'pipe']).
  2. If the spawn result shape is { process, initialization }, ensure `process` is the actual ChildProcess with working streams.
  3. Add a pre-check in the spawn callback that returns the ChildProcess only when stdin/stdout are present.
  4. Catch this error during initialize() and log the spawn args to identify the misconfigured stdio option.

Example fix

// before
spawn(command, args, { stdio: 'ignore' }); // stdin/stdout null
// after
spawn(command, args, { stdio: ['pipe', 'pipe', 'pipe'] });
Defensive patterns

Strategy: validation

Validate before calling

import type { ChildProcess } from 'node:child_process';
function hasValidStdio(p: ChildProcess | null | undefined): p is ChildProcess & { stdin: NonNullable<ChildProcess['stdin']>; stdout: NonNullable<ChildProcess['stdout']> } {
  return !!p && p.stdin != null && p.stdout != null;
}
// validate the result of spawn before handing it to LSPClient

Type guard

function isSpawnableProcess(p: unknown): p is ChildProcess & { stdin: NodeJS.WritableStream; stdout: NodeJS.ReadableStream } {
  const c = p as ChildProcess | undefined;
  return !!c && typeof c.pid === 'number' && c.stdin != null && c.stdout != null;
}

Try / catch

try {
  await client.initialize();
} catch (e) {
  if (e.message === 'Failed to create LSP process with proper stdio') {
    throw new Error(`LSP server '${serverInfo.command}' must be spawned with piped stdin/stdout (stdio: 'pipe')`);
  }
  throw e;
}

Prevention

When it happens

Trigger: serverInfo.spawn returned a process-like object whose stdin/stdout are null — e.g. spawn created with stdio: 'ignore' or piped incorrectly, a custom spawn implementation returning an object without proper stdio streams, or the process exited immediately destroying streams before the check.

Common situations: Custom LSPServerInfo implementations using stdio options other than 'pipe'/'jsonrpc' for stdin/stdout; a server wrapper that detaches stdio; spawn options like detached:true with stdio 'ignore'.

Related errors


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