microsoft/typescript-go · error

failed to create pipe transport: %w

Error message

failed to create pipe transport: %w

What it means

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.

Source

Thrown at internal/api/server.go:62

// NewStdioServer creates a new STDIO-based API server.
func NewStdioServer(options *StdioServerOptions) *StdioServer {
	if options.Cwd == "" {
		panic("StdioServerOptions.Cwd is required")
	}

	return &StdioServer{
		options: options,
	}
}

// Run starts the server and blocks until the connection closes.
func (s *StdioServer) Run(ctx context.Context) error {
	var transport Transport
	if s.options.PipePath != "" {
		t, err := NewPipeTransport(s.options.PipePath)
		if err != nil {
			return fmt.Errorf("failed to create pipe transport: %w", err)
		}
		defer t.Close()
		transport = t
	} else {
		t := NewStdioTransport(s.options.In, s.options.Out)
		defer t.Close()
		transport = t
	}

	fs := bundled.WrapFS(osvfs.FS())

	// Wrap the base FS with callbackFS if callbacks are requested
	var callbackFS *callbackFS
	if len(s.options.Callbacks) > 0 {
		callbackFS = newCallbackFS(fs, s.options.Callbacks)
		fs = callbackFS
	}

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Remove the stale socket file at PipePath before starting (os.Remove(path), ignoring not-exist), then retry Run
  2. Use a unique PipePath per server instance (e.g. include PID or generate a temp name) to avoid collisions
  3. Shorten the path so it fits the OS limit, or place sockets in a short directory like /tmp
  4. 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

Example fix

// before
srv := api.NewStdioServer(&api.StdioServerOptions{Cwd: cwd, PipePath: "/tmp/ts-api.sock"})
err := srv.Run(ctx) // failed to create pipe transport: address already in use

// after
const sock = "/tmp/ts-api.sock"
if _, err := os.Stat(sock); err == nil {
    _ = os.Remove(sock) // clear stale socket from a crashed run
}
srv := api.NewStdioServer(&api.StdioServerOptions{Cwd: cwd, PipePath: sock})
err := srv.Run(ctx)
Defensive patterns

Strategy: validation

Validate before calling

// Go: clear a stale socket and sanity-check the path before Run.
func preparePipePath(path string) error {
    if fi, err := os.Stat(path); err == nil {
        if fi.Mode()&os.ModeSocket != 0 {
            if err := os.Remove(path); err != nil {
                return fmt.Errorf("stale socket %s not removable: %w", path, err)
            }
        } else {
            return fmt.Errorf("%s exists and is not a socket", path)
        }
    }
    if runtime.GOOS != "windows" && len(path) >= 104 {
        return fmt.Errorf("socket path too long for AF_UNIX: %s", path)
    }
    return nil
}

Try / catch

err := srv.Run(ctx)
if err != nil && strings.Contains(err.Error(), "failed to create pipe transport") {
    cause := errors.Unwrap(err)
    if errors.Is(cause, syscall.EADDRINUSE) {
        // stale socket: remove and restart once
        _ = os.Remove(pipePath)
        err = srv.Run(ctx)
    }
}

Prevention

When it happens

Trigger: 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\.

Common situations: 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.

Related errors


AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16). Data as JSON: /api/errors/ad2680f707c676a2. Report an issue: GitHub.