{"record":{"id":"191d7e666ddb1388","repo":"charmbracelet/glow","slug":"unable-to-stat-file-w","errorCode":null,"errorMessage":"unable to stat file: %w","messagePattern":"unable to stat file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"main.go","lineNumber":160,"sourceCode":"\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to open file: %w\", err)\n\t}\n\tu, err := filepath.Abs(arg)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to get absolute path: %w\", err)\n\t}\n\treturn &source{r, u}, nil\n}\n\n// validateStyle checks if the style is a default style, if not, checks that\n// the custom style exists.\nfunc validateStyle(style string) error {\n\tif style != \"auto\" && styles.DefaultStyles[style] == nil {\n\t\tstyle = utils.ExpandPath(style)\n\t\tif _, err := os.Stat(style); errors.Is(err, fs.ErrNotExist) {\n\t\t\treturn fmt.Errorf(\"specified style does not exist: %s\", style)\n\t\t} else if err != nil {\n\t\t\treturn fmt.Errorf(\"unable to stat file: %w\", err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc validateOptions(cmd *cobra.Command) error {\n\t// grab config values from Viper\n\twidth = viper.GetUint(\"width\")\n\tmouse = viper.GetBool(\"mouse\")\n\tpager = viper.GetBool(\"pager\")\n\ttui = viper.GetBool(\"tui\")\n\tshowAllFiles = viper.GetBool(\"all\")\n\tpreserveNewLines = viper.GetBool(\"preserveNewLines\")\n\tshowLineNumbers = viper.GetBool(\"showLineNumbers\")\n\n\tif pager && tui {\n\t\treturn errors.New(\"cannot use both pager and tui\")\n\t}","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/charmbracelet/glow/blob/e3970c813d93da1ea84edfca90c289d9afb82242/main.go#L142-L178","documentation":"The same validateStyle stat call, but for errors other than fs.ErrNotExist - the raw OS error is wrapped with %w. This means the style path could be located but stat-ing it failed: a parent directory lacks search permission (EACCES), a stale network mount (EIO), or the path exceeds limits (ENAMETOOLONG).","triggerScenarios":"A parent directory in the style path is not traversable by the user; the style file sits on a stale NFS/fuse mount; the path is longer than PATH_MAX.","commonSituations":"Styles kept on network home directories that went stale, restricted multi-user machines, deeply nested config directories exceeding path limits.","solutions":["Check traversability of each component: namei -l /path/to/style.json","Repair or remount stale network mounts","Shorten the path or move the style file to local disk"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"func traversable(path string) error {\n\tfor dir := path; dir != \"/\" && dir != \".\"; dir = filepath.Dir(dir) {\n\t\tif _, err := os.Stat(dir); err != nil { return fmt.Errorf(\"%s: %w\", dir, err) }\n\t}\n\treturn nil\n}","typeGuard":"func isPermissionErr(err error) bool { return errors.Is(err, fs.ErrPermission) }","tryCatchPattern":"if _, err := os.Stat(stylePath); err != nil {\n\tswitch {\n\tcase errors.Is(err, fs.ErrNotExist):\n\t\t// style file missing: use a built-in style\n\tcase errors.Is(err, fs.ErrPermission):\n\t\t// parent traversal denied: report the offending dir\n\tdefault:\n\t\t// I/O or path-length error: surface the wrapped error\n\t}\n}","preventionTips":["Distinguish fs.ErrNotExist from fs.ErrPermission and I/O errors when stat-ing style files","Keep style files on local disk rather than network mounts","Audit parent-directory permissions after moving configs"],"tags":["filesystem","style","permissions"],"backgroundTag":null,"analyzedSha":"e3970c813d93da1ea84edfca90c289d9afb82242","analyzedAt":"2026-08-15T22:50:54.304Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}