{"record":{"id":"44058c79dbd7cd92","repo":"JuliusBrussee/caveman","slug":"native-runtime-listen-w","errorCode":null,"errorMessage":"native runtime listen: %w","messagePattern":"native runtime listen: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/internal/nativeruntime/server_unix.go","lineNumber":56,"sourceCode":"\t}\n\tif err := os.Chmod(filepath.Dir(path), 0o700); err != nil {\n\t\treturn fmt.Errorf(\"native runtime chmod dir: %w\", err)\n\t}\n\tif _, err := os.Stat(path); err == nil {\n\t\tconn, dialErr := net.DialTimeout(\"unix\", path, 50*time.Millisecond)\n\t\tif dialErr == nil {\n\t\t\t_ = conn.Close()\n\t\t\treturn errors.New(\"native runtime: socket already active\")\n\t\t}\n\t\tif err := os.Remove(path); err != nil {\n\t\t\treturn fmt.Errorf(\"native runtime remove stale socket: %w\", err)\n\t\t}\n\t} else if !os.IsNotExist(err) {\n\t\treturn fmt.Errorf(\"native runtime inspect socket: %w\", err)\n\t}\n\tlistener, err := net.Listen(\"unix\", path)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"native runtime listen: %w\", err)\n\t}\n\tdefer listener.Close()\n\tdefer os.Remove(path)\n\tif err := os.Chmod(path, 0o600); err != nil {\n\t\treturn fmt.Errorf(\"native runtime chmod socket: %w\", err)\n\t}\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 {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"native runtime accept: %w\", err)\n\t\t}","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/proxy/internal/nativeruntime/server_unix.go#L38-L74","documentation":"Returned when net.Listen(\"unix\", path) fails while the native runtime is trying to bind its local Unix socket. The server had just cleaned (or verified absent) a stale socket, so this usually means the path is unwritable, too long, or another process created a socket between the stale check and the listen.","triggerScenarios":"Calling nativeruntime.Serve on Unix when (a) the parent directory of the socket path does not exist or lacks write permission, (b) the socket path exceeds the ~104-108 byte sun_path limit, or (c) a second caveman process started concurrently and won the listen race after the stale-socket probe.","commonSituations":"HOME points to a read-only or non-existent directory; a leftover-but-active listener from an earlier run (socket-active check passed only for a dead peer); running two instances with the same home; deeply nested home paths blowing past the Unix socket path-length limit.","solutions":["Check that the socket's parent directory (home/run or equivalent) exists and is writable by the current user","Ensure no second caveman process is already serving the same home (lsof on the socket path); stop it or use a different home","Shorten the socket path — put home closer to the filesystem root or raise the home directory if the path exceeds the OS sun_path limit","If the directory is on a filesystem that does not support Unix sockets (some network mounts), move home to a local filesystem"],"exampleFix":"// before: home deep under a long path, listen fails with 'invalid argument'\nhome := \"/very/long/nested/path/that/exceeds/unix/socket/limits/.caveman\"\nerr := nativeruntime.Serve(ctx, home, rt)\n\n// after: keep the socket path short\nhome := \"/home/user/.caveman\"\nerr := nativeruntime.Serve(ctx, home, rt)","handlingStrategy":"validation","validationCode":"dir := filepath.Dir(sockPath)\nif info, err := os.Stat(dir); err != nil || !info.IsDir() {\n    return fmt.Errorf(\"socket directory %s missing\", dir)\n}\nif len(sockPath) >= 104 { // typical sun_path limit\n    return fmt.Errorf(\"socket path too long (%d bytes)\", len(sockPath))\n}","typeGuard":null,"tryCatchPattern":"if err := nativeruntime.Serve(ctx, home, rt); err != nil {\n    if strings.Contains(err.Error(), \"native runtime listen\") {\n        // inspect %w chain: errors.Is(err, os.ErrPermission) vs syscall.EADDRINUSE\n    }\n    return err\n}","preventionTips":["Create the socket's parent directory with 0700 before starting Serve","Keep the home directory path short; avoid deeply nested homes on Unix","Run one server per home; probe with a dial first if unsure"],"tags":["unix-socket","nativeruntime","filesystem","go"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}