{"record":{"id":"561a25249209e84e","repo":"microsoft/typescript-go","slug":"failed-to-accept-connection-w","errorCode":null,"errorMessage":"failed to accept connection: %w","messagePattern":"failed to accept connection: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/api/server.go","lineNumber":101,"sourceCode":"\t\tLogger:        nil, // TODO: Add logging support\n\t\tFS:            fs,\n\t\tOptions: &project.SessionOptions{\n\t\t\tCurrentDirectory:   s.options.Cwd,\n\t\t\tDefaultLibraryPath: s.options.DefaultLibraryPath,\n\t\t\tPositionEncoding:   lsproto.PositionEncodingKindUTF8,\n\t\t\tLoggingEnabled:     false,\n\t\t},\n\t})\n\n\tsession := NewSession(projectSession, &SessionOptions{\n\t\tUseBinaryResponses: !s.options.Async, // Only msgpack uses binary responses\n\t})\n\tdefer session.Close()\n\n\t// Accept connection from transport\n\trwc, err := transport.Accept()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to accept connection: %w\", err)\n\t}\n\n\t// Create protocol and connection based on async mode\n\tvar conn Conn\n\tif s.options.Async {\n\t\tprotocol := NewJSONRPCProtocol(rwc)\n\t\tasyncConn := NewAsyncConnWithProtocol(rwc, protocol, session)\n\t\tasyncConn.SetCollectTiming(s.options.CollectTiming)\n\t\tconn = asyncConn\n\t} else {\n\t\tprotocol := NewMessagePackProtocol(rwc)\n\t\tsyncConn := NewSyncConn(rwc, protocol, session)\n\t\tsyncConn.SetCollectTiming(s.options.CollectTiming)\n\t\tconn = syncConn\n\t}\n\n\t// If callbacks are enabled, set the connection on the FS\n\tif callbackFS != nil {","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/microsoft/typescript-go/blob/1bcfa18d79a3be41772223d5c05dfe4480e614ff/internal/api/server.go#L83-L119","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nif err := srv.Run(ctx); err != nil {\n    log.Fatalf(\"server failed: %v\", err) // accept error crashes the host\n}\n\n// after\nif err := srv.Run(ctx); err != nil {\n    if errors.Is(err, net.ErrClosed) || errors.Is(err, context.Canceled) {\n        return // deliberate shutdown\n    }\n    log.Printf(\"server failed: %v\", err)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := srv.Run(ctx)\nswitch {\ncase err == nil, errors.Is(err, net.ErrClosed), errors.Is(err, context.Canceled):\n    // deliberate shutdown - nothing to retry\ncase errors.Is(err, syscall.ECONNABORTED) || errors.Is(err, syscall.EMFILE):\n    // transient: brief backoff, then rebuild transport + retry once\n    time.Sleep(100 * time.Millisecond)\n    err = srv.Run(ctx)\n    if err != nil { log.Printf(\"accept retry failed: %v\", err) }\ndefault:\n    log.Printf(\"accept failed: %v\", err) // e.g. socket unlinked - recreate transport\n}","preventionTips":["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"],"tags":["transport","network","connection","accept","lifecycle"],"backgroundTag":null,"analyzedSha":"1bcfa18d79a3be41772223d5c05dfe4480e614ff","analyzedAt":"2026-08-16T02:12:00.115Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}