{"record":{"id":"b4f349c663f4da89","repo":"wavetermdev/waveterm","slug":"cannot-create-stdin-pipe-w","errorCode":null,"errorMessage":"cannot create stdin pipe: %w","messagePattern":"cannot create stdin pipe: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshrpc/wshremote/wshremote_job.go","lineNumber":159,"sourceCode":"\t\treturn nil, err\n\t}\n\tlog.Printf(\"RemoteStartJobCommand: wshPath=%s\\n\", wshPath)\n\n\treadyPipeRead, readyPipeWrite, err := os.Pipe()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot create ready pipe: %w\", err)\n\t}\n\tdefer readyPipeRead.Close()\n\tdefer readyPipeWrite.Close()\n\n\tcmd := exec.Command(wshPath, \"jobmanager\", \"--jobid\", data.JobId, \"--clientid\", data.ClientId)\n\tif data.PublicKeyBase64 != \"\" {\n\t\tcmd.Env = append(os.Environ(), \"WAVETERM_PUBLICKEY=\"+data.PublicKeyBase64)\n\t}\n\tcmd.ExtraFiles = []*os.File{readyPipeWrite}\n\tstdin, err := cmd.StdinPipe()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot create stdin pipe: %w\", err)\n\t}\n\tstdout, err := cmd.StdoutPipe()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot create stdout pipe: %w\", err)\n\t}\n\tstderr, err := cmd.StderrPipe()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot create stderr pipe: %w\", err)\n\t}\n\tlog.Printf(\"RemoteStartJobCommand: created pipes\\n\")\n\n\tif err := cmd.Start(); err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot start job manager: %w\", err)\n\t}\n\treadyPipeWrite.Close()\n\tlog.Printf(\"RemoteStartJobCommand: job manager process started\\n\")\n\n\tjobAuthTokenLine := fmt.Sprintf(\"Wave-JobAccessToken:%s\\n\", data.JobAuthToken)","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshrpc/wshremote/wshremote_job.go#L141-L177","documentation":"cmd.StdinPipe() failed while creating the stdin pipe used to deliver the job auth token to the wsh jobmanager child. StdinPipe creates an os.Pipe internally, so this is again an fd/resource allocation failure wrapped with %w.","triggerScenarios":"Calling RemoteStartJobCommand when pipe creation fails due to fd exhaustion or an OS-level pipe limit being reached.","commonSituations":"fd leaks accumulating across many spawned jobs; hitting the kernel pipe/fd limit on constrained hosts or containers.","solutions":["Fix fd leaks in the parent process and ensure pipes are closed after each job","Raise RLIMIT_NOFILE (ulimit -n) for the server process","Restart the server process if descriptors are exhausted"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"var lim syscall.Rlimit\nsyscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim)\nif lim.Cur < 1024 {\n    return fmt.Errorf(\"fd limit too low (%d) to spawn job manager\", lim.Cur)\n}","typeGuard":null,"tryCatchPattern":"rtn, err := server.RemoteStartJobCommand(ctx, data)\nif err != nil {\n    if strings.Contains(err.Error(), \"cannot create stdin pipe\") {\n        // fd exhaustion: leak-check and retry after raising limits\n    }\n    return err\n}","preventionTips":["Track fds per job lifecycle; ensure StdinPipe is closed after token write (the code does this)","Raise RLIMIT_NOFILE for the server","Cap concurrent job starts"],"tags":["os","file-descriptors","pipes","exec"],"backgroundTag":"too-many-open-files","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}