{"record":{"id":"f8d52ee29c47e052","repo":"anomalyco/sst","slug":"failed-to-create-stdout-pipe-v","errorCode":null,"errorMessage":"failed to create stdout pipe: %v","messagePattern":"failed to create stdout pipe: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/runtime/python/python.go","lineNumber":202,"sourceCode":"\t\t// Add src/ if it exists\n\t\tsrcDir := filepath.Join(projectRoot, \"src\")\n\t\tif _, err := os.Stat(srcDir); err == nil {\n\t\t\tpythonPaths = append(pythonPaths, srcDir)\n\t\t}\n\n\t\t// Join paths\n\t\tpythonPath := strings.Join(pythonPaths, string(os.PathListSeparator))\n\t\tenv = append(env, \"PYTHONPATH=\"+pythonPath)\n\n\t\tresourceEncPath := filepath.Join(input.Build.Out, \"resource.enc\")\n\t\tenv = append(env, \"SST_KEY_FILE=\"+resourceEncPath)\n\t}\n\n\tcmd.Env = env\n\tcmd.Dir = workingDir\n\tstdout, err := cmd.StdoutPipe()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create stdout pipe: %v\", err)\n\t}\n\tstderr, err := cmd.StderrPipe()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create stderr pipe: %v\", err)\n\t}\n\n\tif err := cmd.Start(); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to start worker process: %v\", err)\n\t}\n\n\treturn &worker{\n\t\tstdout,\n\t\tstderr,\n\t\tcmd,\n\t}, nil\n\n}\n","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/pkg/runtime/python/python.go#L184-L220","documentation":"Raised in PythonRuntime.Run (pkg/runtime/python/python.go:202) when cmd.StdoutPipe() on the `uv run lambdaric_python_bridge.py <handler>` worker process fails. StdoutPipe only fails if the exec.Cmd was already started or waited on, or in rare OS pipe-creation failures (fd exhaustion). It is a guard branch that almost never fires in normal use, indicating a runtime misuse or resource exhaustion.","triggerScenarios":"Calling Run twice reusing the same exec.Cmd (pipe already created/started), or the OS refusing to allocate a new pipe because the process is out of file descriptors (ulimit -n too low with many concurrent functions).","commonSituations":"Dev servers spawning dozens of Python workers in parallel (default build concurrency is 4, but many function workers) hitting ulimit -n; custom forks that re-invoke cmd after Start(); constrained CI containers with very low fd limits.","solutions":["Check the wrapped %v cause: if it mentions 'already started' or 'exec: StdoutPipe after Start', ensure a fresh exec.Cmd is used per Run call","Raise the file-descriptor limit (ulimit -n 4096 or higher) and reduce concurrentsst dev workers via SST_BUILD_CONCURRENCY","Free leaked fd/pipe resources elsewhere in the process (unstopped workers); ensure worker.Stop() is called","Retry the dev command after clearing leaked processes: pkill -f lambdaric_python_bridge"],"exampleFix":"// before: reusing a cmd\nstdout, _ := cmd.StdoutPipe()\ncmd.Start()\nstdout2, err := cmd.StdoutPipe() // fails: exec: StdoutPipe after Start\n// after: build a fresh cmd for each worker\ncmd := process.CommandContext(ctx, \"uv\", \"run\", bridge, handler)","handlingStrategy":"try-catch","validationCode":"// before spawning many workers, check fd headroom (Linux/macOS)\nn, err := strconv.Atoi(strings.TrimSuffix(shellOut(\"ulimit\", \"-n\"), \"\\n\"))\nif err == nil && n < 1024 { fmt.Println(\"raise ulimit -n before running sst dev\") }","typeGuard":null,"tryCatchPattern":"w, err := rt.Run(ctx, input)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to create stdout pipe\") {\n        // fd exhaustion or cmd reuse: reduce concurrency / retry with fresh cmd\n        return retryWithFreshCommand(ctx, input)\n    }\n    return err\n}","preventionTips":["Call worker.Stop() for every started worker so pipes/fds are released","Keep ulimit -n comfortably above the number of concurrent Python functions","Never reuse an exec.Cmd after Start(); construct a new one per invocation","Cap concurrency via SST_BUILD_CONCURRENCY on fd-constrained CI runners"],"tags":["process","pipe","file-descriptors","go"],"backgroundTag":"process-spawn-failed","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}