{"record":{"id":"a77ec8772eb47618","repo":"neoclide/coc.nvim","slug":"process-created-without-stdio-streams","errorCode":null,"errorMessage":"Process created without stdio streams","messagePattern":"Process created without stdio streams","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/language-client/index.ts","lineNumber":266,"sourceCode":"\n  protected createMessageTransports(encoding: string): Promise<MessageTransports> {\n\n    function getEnvironment(env: any, fork: boolean): any {\n      if (!env && !fork) {\n        return undefined\n      }\n      let result: any = Object.create(null)\n      Object.keys(process.env).forEach(key => result[key] = process.env[key])\n      if (env) {\n        Object.keys(env).forEach(key => result[key] = env[key])\n      }\n      return result\n    }\n\n    function assertStdio(process: ChildProcess): asserts process is ChildProcessWithoutNullStreams {\n      if (process.stdin === null || process.stdout === null || process.stderr === null) {\n        process.kill('SIGKILL')\n        throw new Error('Process created without stdio streams')\n      }\n    }\n\n    function logMessage(kind: string, data: string, outputChannel: OutputChannel): void {\n      let msg = `[${kind} - ${currentTimeStamp()}] ${data}`\n      outputChannel.appendLine(msg)\n    }\n\n    function pipeStdoutToLogOutputChannel(input: stream.Readable, outputChannel: OutputChannel) {\n      readline.createInterface({\n        input,\n        crlfDelay: Infinity,\n        terminal: false,\n        historySize: 0,\n      }).on('line', data => logMessage('Stdout', data, outputChannel))\n    }\n\n    function pipeStderrToLogOutputChannel(input: stream.Readable, outputChannel: OutputChannel) {","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/neoclide/coc.nvim/blob/50e974d9692461a69147d5cab146a8d3e439abe4/src/language-client/index.ts#L248-L284","documentation":"When spawning the language server as a child process with stdio transport, the client asserts stdin/stdout/stderr are all non-null. If Node returned null streams (process failed to get pipes), the process is SIGKILLed and this error is thrown instead of hanging on a dead transport.","triggerScenarios":"server module launched with a command that Node could not attach stdio pipes to (e.g. executable options overriding stdio, spawn environment issues, or a command that immediately detaches).","commonSituations":"Server options inadvertently setting stdio: 'ignore'; spawning GUI wrappers that don't inherit stdio; resource limits preventing pipe creation; wrong executable path combined with shell wrappers.","solutions":["Do not override stdio in child_process spawn options for the server","Verify the server command is a real executable that keeps stdio attached","Remove shell wrappers (cmd /c, .bat indirection) or ensure they forward stdio","Check Node version; spawn with the correct ChildProcessSpawnOptions"],"exampleFix":"// before\nconst serverOptions: ServerOptions = () => spawn(cmd, args, { stdio: 'ignore' })\n// after\nconst serverOptions: ServerOptions = () => spawn(cmd, args) // stdio pipes created by default","handlingStrategy":"validation","validationCode":"// Before starting the server, verify the command exists and options don't override stdio\nif (!opts.stdio && !commandExists(serverCommand)) {\n  throw new Error(`Server command not found: ${serverCommand}`)\n}","typeGuard":"function hasNullStreams(p: ChildProcess): boolean {\n  return p.stdin === null || p.stdout === null || p.stderr === null\n}","tryCatchPattern":"try {\n  const client = new LanguageClient(id, name, serverOptions, clientOptions)\n  await client.start()\n} catch (e) {\n  if (String(e.message).includes('without stdio streams')) {\n    console.error('Server spawn failed to attach stdio; check command/options')\n  } else { throw e }\n}","preventionTips":["Never set stdio overrides in spawn options for the language server","Verify the server binary runs standalone and keeps stdio open","Avoid shell wrappers that swallow stdio","Check process.exit/error events on the child for early termination"],"tags":["child-process","stdio","spawn","language-server"],"backgroundTag":"missing-stdio-streams","analyzedSha":"50e974d9692461a69147d5cab146a8d3e439abe4","analyzedAt":"2026-08-31T11:17:23.966Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}