microsoft/typescript-go · error
failed to accept connection: %w
Error message
failed to accept connection: %w
What it means
StdioServer.Run could not accept the client connection: transport.Accept() returned an error. With PipePath set this is the net.Listener's Accept failing (listener closed, socket unlinked from the filesystem, or fd exhaustion); with the default stdio transport it is effectively unreachable on the first call (Accept wraps stdin/stdout once and only returns io.EOF on a second call). The wrapped error carries the OS cause.
Source
Thrown at internal/api/server.go:101
Logger: nil, // TODO: Add logging support
FS: fs,
Options: &project.SessionOptions{
CurrentDirectory: s.options.Cwd,
DefaultLibraryPath: s.options.DefaultLibraryPath,
PositionEncoding: lsproto.PositionEncodingKindUTF8,
LoggingEnabled: false,
},
})
session := NewSession(projectSession, &SessionOptions{
UseBinaryResponses: !s.options.Async, // Only msgpack uses binary responses
})
defer session.Close()
// Accept connection from transport
rwc, err := transport.Accept()
if err != nil {
return fmt.Errorf("failed to accept connection: %w", err)
}
// Create protocol and connection based on async mode
var conn Conn
if s.options.Async {
protocol := NewJSONRPCProtocol(rwc)
asyncConn := NewAsyncConnWithProtocol(rwc, protocol, session)
asyncConn.SetCollectTiming(s.options.CollectTiming)
conn = asyncConn
} else {
protocol := NewMessagePackProtocol(rwc)
syncConn := NewSyncConn(rwc, protocol, session)
syncConn.SetCollectTiming(s.options.CollectTiming)
conn = syncConn
}
// If callbacks are enabled, set the connection on the FS
if callbackFS != nil {View on GitHub (pinned to 1bcfa18d79)
Solutions
- Check the wrapped cause: net.ErrClosed means intentional shutdown (treat as benign), EMFILE means raise the fd limit, 'no such file or directory' means the socket was unlinked - recreate the transport
- Ensure the socket path lives in a directory nothing else cleans while the server runs
- Create a fresh StdioServer per connection; Run is one-shot for the stdio transport
- Raise ulimit -n / handle limits if fd exhaustion recurs
Example fix
// before
if err := srv.Run(ctx); err != nil {
log.Fatalf("server failed: %v", err) // accept error crashes the host
}
// after
if err := srv.Run(ctx); err != nil {
if errors.Is(err, net.ErrClosed) || errors.Is(err, context.Canceled) {
return // deliberate shutdown
}
log.Printf("server failed: %v", err)
} Defensive patterns
Strategy: retry
Try / catch
err := srv.Run(ctx)
switch {
case err == nil, errors.Is(err, net.ErrClosed), errors.Is(err, context.Canceled):
// deliberate shutdown - nothing to retry
case errors.Is(err, syscall.ECONNABORTED) || errors.Is(err, syscall.EMFILE):
// transient: brief backoff, then rebuild transport + retry once
time.Sleep(100 * time.Millisecond)
err = srv.Run(ctx)
if err != nil { log.Printf("accept retry failed: %v", err) }
default:
log.Printf("accept failed: %v", err) // e.g. socket unlinked - recreate transport
} Prevention
- Keep the socket in a directory no cleaner daemon purges during the session
- Check fd limits (ulimit -n) on long-lived hosts that open many connections
- Create a new StdioServer per connection; Run accepts exactly one connection for stdio
- Watch for ctx cancellation shutting the listener down concurrently with the first connect
When it happens
Trigger: The unix socket file was deleted out from under the listener (another process cleans the temp dir) so Accept fails; the process hit its file-descriptor limit (EMFILE) when the client connected; the listener was closed concurrently (e.g. ctx-driven teardown closing the transport) before the client connected; calling Run twice on the same StdioServer so the second Accept returns io.EOF.
Common situations: Temp-dir cleaners (systemd-tmpfiles, CI workspace wipes) removing the socket path while the server waits; heavily loaded hosts exhausting fds; a host supervisor racing shutdown with the first client connect; test harnesses that reuse a server instance across connections.
Related errors
- failed to create pipe transport: %w
- npm pack ${npmPackageName}@${version} did not return a filen
- Language server is not running.
- Cannot run a temporary file update on an inactive snapshot
- Snapshot is disposed
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/561a25249209e84e.
Report an issue: GitHub.