{"record":{"id":"ad2680f707c676a2","repo":"microsoft/typescript-go","slug":"failed-to-create-pipe-transport-w","errorCode":null,"errorMessage":"failed to create pipe transport: %w","messagePattern":"failed to create pipe transport: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/api/server.go","lineNumber":62,"sourceCode":"\n// NewStdioServer creates a new STDIO-based API server.\nfunc NewStdioServer(options *StdioServerOptions) *StdioServer {\n\tif options.Cwd == \"\" {\n\t\tpanic(\"StdioServerOptions.Cwd is required\")\n\t}\n\n\treturn &StdioServer{\n\t\toptions: options,\n\t}\n}\n\n// Run starts the server and blocks until the connection closes.\nfunc (s *StdioServer) Run(ctx context.Context) error {\n\tvar transport Transport\n\tif s.options.PipePath != \"\" {\n\t\tt, err := NewPipeTransport(s.options.PipePath)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create pipe transport: %w\", err)\n\t\t}\n\t\tdefer t.Close()\n\t\ttransport = t\n\t} else {\n\t\tt := NewStdioTransport(s.options.In, s.options.Out)\n\t\tdefer t.Close()\n\t\ttransport = t\n\t}\n\n\tfs := bundled.WrapFS(osvfs.FS())\n\n\t// Wrap the base FS with callbackFS if callbacks are requested\n\tvar callbackFS *callbackFS\n\tif len(s.options.Callbacks) > 0 {\n\t\tcallbackFS = newCallbackFS(fs, s.options.Callbacks)\n\t\tfs = callbackFS\n\t}\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/microsoft/typescript-go/blob/1bcfa18d79a3be41772223d5c05dfe4480e614ff/internal/api/server.go#L44-L80","documentation":"StdioServer.Run failed to create the pipe transport: NewPipeTransport could not listen on the configured PipePath (a Unix domain socket on Unix, a named pipe on Windows). The underlying net.Listen error is wrapped, so the message includes the OS-level cause (address already in use, permission denied, socket path too long, invalid pipe name). The server cannot start and Run returns before accepting any connection.","triggerScenarios":"A stale socket file already exists at PipePath from a previous crashed process (EADDRINUSE); the socket path exceeds the ~108-byte Unix domain socket limit; permission denied on the directory; two server instances configured with the same PipePath; a malformed Windows pipe name that is not under \\\\.\\pipe\\.","commonSituations":"Restarting a tool whose previous process did not clean up its socket; long temp-dir paths (CI runners, macOS $TMPDIR) blowing past the unix socket path limit; running two editor integrations side by side that both hardcode the same pipe path; sandboxed environments denying unix socket creation.","solutions":["Remove the stale socket file at PipePath before starting (os.Remove(path), ignoring not-exist), then retry Run","Use a unique PipePath per server instance (e.g. include PID or generate a temp name) to avoid collisions","Shorten the path so it fits the OS limit, or place sockets in a short directory like /tmp","Check the wrapped error text for the OS cause: 'address already in use' -> stale socket, 'permission denied' -> directory rights, 'invalid argument' -> bad pipe name/format"],"exampleFix":"// before\nsrv := api.NewStdioServer(&api.StdioServerOptions{Cwd: cwd, PipePath: \"/tmp/ts-api.sock\"})\nerr := srv.Run(ctx) // failed to create pipe transport: address already in use\n\n// after\nconst sock = \"/tmp/ts-api.sock\"\nif _, err := os.Stat(sock); err == nil {\n    _ = os.Remove(sock) // clear stale socket from a crashed run\n}\nsrv := api.NewStdioServer(&api.StdioServerOptions{Cwd: cwd, PipePath: sock})\nerr := srv.Run(ctx)","handlingStrategy":"validation","validationCode":"// Go: clear a stale socket and sanity-check the path before Run.\nfunc preparePipePath(path string) error {\n    if fi, err := os.Stat(path); err == nil {\n        if fi.Mode()&os.ModeSocket != 0 {\n            if err := os.Remove(path); err != nil {\n                return fmt.Errorf(\"stale socket %s not removable: %w\", path, err)\n            }\n        } else {\n            return fmt.Errorf(\"%s exists and is not a socket\", path)\n        }\n    }\n    if runtime.GOOS != \"windows\" && len(path) >= 104 {\n        return fmt.Errorf(\"socket path too long for AF_UNIX: %s\", path)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"err := srv.Run(ctx)\nif err != nil && strings.Contains(err.Error(), \"failed to create pipe transport\") {\n    cause := errors.Unwrap(err)\n    if errors.Is(cause, syscall.EADDRINUSE) {\n        // stale socket: remove and restart once\n        _ = os.Remove(pipePath)\n        err = srv.Run(ctx)\n    }\n}","preventionTips":["Include the PID in the pipe path so concurrent instances never collide","Clean up the socket file via defer on server shutdown","Keep socket paths short (/tmp, not nested temp dirs) on Unix","On Windows, use a unique name under \\\\.\\pipe\\"],"tags":["transport","named-pipe","unix-socket","network","configuration","startup"],"backgroundTag":null,"analyzedSha":"1bcfa18d79a3be41772223d5c05dfe4480e614ff","analyzedAt":"2026-08-16T02:12:00.115Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}