{"record":{"id":"5cda62458b8773df","repo":"JuliusBrussee/caveman","slug":"native-runtime-named-pipe-listen-w","errorCode":null,"errorMessage":"native runtime named-pipe listen: %w","messagePattern":"native runtime named-pipe listen: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/internal/nativeruntime/server_windows.go","lineNumber":55,"sourceCode":"func Serve(ctx context.Context, home string, runtime *Runtime) error {\n\tif runtime == nil || runtime.store == nil {\n\t\treturn errors.New(\"native runtime: store is required\")\n\t}\n\tuser, err := windows.GetCurrentProcessToken().GetTokenUser()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"native runtime current user SID: %w\", err)\n\t}\n\tif user == nil || user.User.Sid == nil {\n\t\treturn errors.New(\"native runtime current user SID: unavailable\")\n\t}\n\tsddl := \"D:P(A;;GA;;;\" + user.User.Sid.String() + \")\"\n\tlistener, err := winio.ListenPipe(SocketPath(home), &winio.PipeConfig{\n\t\tSecurityDescriptor: sddl,\n\t\tInputBufferSize:    maxRequestBytes,\n\t\tOutputBufferSize:   maxRequestBytes,\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"native runtime named-pipe listen: %w\", err)\n\t}\n\tdefer listener.Close()\n\tgo func() {\n\t\t<-ctx.Done()\n\t\t_ = listener.Close()\n\t}()\n\tfor {\n\t\tconn, err := listener.Accept()\n\t\tif err != nil {\n\t\t\tif ctx.Err() != nil || errors.Is(err, net.ErrClosed) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"native runtime named-pipe accept: %w\", err)\n\t\t}\n\t\tgo serveConn(ctx, conn, runtime)\n\t}\n}\n","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/proxy/internal/nativeruntime/server_windows.go#L37-L73","documentation":"Returned when winio.ListenPipe fails to create the Windows named pipe for the native runtime. This wraps CreateNamedPipe errors: the pipe name is already in use, the path is invalid, or the process lacks rights to create an object in that namespace.","triggerScenarios":"Calling Serve on Windows when another caveman instance already listens on the same pipe name (winio pipes are exclusive in FILE_FLAG_FIRST_PIPE_INSTANCE terms), or the pipe path (derived from home) contains characters invalid in the \\\\.\\pipe\\ namespace.","commonSituations":"Two instances sharing one home directory; a crashed instance whose pipe handle is still held by a child process; pipe names longer than 256 chars from a deep home path; antivirus/security software holding or blocking pipe creation.","solutions":["Check for and stop any other process serving the same home (Get-ChildItem \\\\.\\pipe\\ | findstr or Process Explorer handle search)","Restart the previous instance's orphaned children that still hold pipe handles, or reboot to clear stale handles","Shorten home so the derived pipe name stays well under the 256-character pipe-name limit","Temporarily disable/reconfigure AV interference if it is blocking pipe creation"],"exampleFix":"// before: second instance while first still runs\nerr := nativeruntime.Serve(ctx, sharedHome, rt)\n\n// after: single instance per home; check the pipe first\nif _, err := winio.DialPipeContext(ctx, pipeName); err == nil {\n    return errors.New(\"native runtime: pipe already active\")\n}\nerr := nativeruntime.Serve(ctx, sharedHome, rt)","handlingStrategy":"validation","validationCode":"// Before Serve on Windows, verify the pipe is free and the name is legal\nname := nativeruntime.SocketPath(home)\nif len(name) > 200 { return fmt.Errorf(\"pipe name too long\") }\nif _, err := winio.DialPipeContext(ctx, name); err == nil {\n    return errors.New(\"pipe already in use\")\n}","typeGuard":null,"tryCatchPattern":"if err := nativeruntime.Serve(ctx, home, rt); err != nil {\n    if errors.Is(err, windows.ERROR_ACCESS_DENIED) || errors.Is(err, os.ErrNotExist) {\n        // pipe namespace conflict or invalid name — check for another instance\n    }\n}","preventionTips":["One instance per home on Windows; pipes are not auto-cleaned like stale Unix sockets","Keep the derived pipe name short (pipe namespace limit is 256 chars)","Add AV/EDR exclusions for the pipe if security software interferes"],"tags":["windows","named-pipe","nativeruntime","go"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}