{"record":{"id":"825302d946bebe27","repo":"charmbracelet/glow","slug":"unable-to-stat-config-file-w","errorCode":null,"errorMessage":"unable to stat config file: %w","messagePattern":"unable to stat config file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"config_cmd.go","lineNumber":85,"sourceCode":"\n\tif _, err := os.Stat(configFile); errors.Is(err, fs.ErrNotExist) {\n\t\t// File doesn't exist yet, create all necessary directories and\n\t\t// write the default config file\n\t\tif err := os.MkdirAll(filepath.Dir(configFile), 0o700); err != nil {\n\t\t\treturn fmt.Errorf(\"unable create directory: %w\", err)\n\t\t}\n\n\t\tf, err := os.Create(configFile)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to create config file: %w\", err)\n\t\t}\n\t\tdefer func() { _ = f.Close() }()\n\n\t\tif _, err := f.WriteString(defaultConfig); err != nil {\n\t\t\treturn fmt.Errorf(\"unable to write config file: %w\", err)\n\t\t}\n\t} else if err != nil { // some other error occurred\n\t\treturn fmt.Errorf(\"unable to stat config file: %w\", err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":67,"sourceCodeEnd":89,"githubUrl":"https://github.com/charmbracelet/glow/blob/e3970c813d93da1ea84edfca90c289d9afb82242/config_cmd.go#L67-L89","documentation":"ensureConfigFile calls os.Stat(configFile) to decide whether the default config must be written. errors.Is(err, fs.ErrNotExist) takes the create branch, but any other stat error — the else-if at the end — is surfaced with this wrapper. So the file's existence is undetermined, not merely absent.","triggerScenarios":"Search/execute permission denied on a parent directory component, so stat cannot traverse to the file (EACCES); a symlink in the path with a broken/looping target causing a non-NotExist error; path longer than PATH_MAX; SELinux denying stat on the context.","commonSituations":"chmod 700 directories owned by another user inside the config path; broken symlink left by a dotfile manager at ~/.config/glow; odd mount namespaces (containers) where a bind-mounted parent disappears.","solutions":["Reproduce manually: stat <configFile> and namei -l <configFile> to find the failing component","Fix traversal permissions: chmod o+x on the blocking directory or chown it","Remove broken symlinks in the path: rm ~/.config/glow (symlink) then retry","Fall back to a clean --config path you control"],"exampleFix":"# before\n$ glow config\n# Error: unable to stat config file: stat /home/u/.config/glow/glow.yml: permission denied\n\n# after\n$ chmod 755 /home/u/.config && glow config","handlingStrategy":"try-catch","validationCode":"// pre-walk the path so a non-NotExist stat failure is caught with context\nfunc probeConfigPath(p string) error {\n\t_, err := os.Stat(p)\n\tswitch {\n\tcase err == nil, errors.Is(err, fs.ErrNotExist):\n\t\treturn nil\n\tcase errors.Is(err, fs.ErrPermission):\n\t\treturn fmt.Errorf(\"cannot traverse to %s: fix mode/ownership on a parent dir\", p)\n\tdefault:\n\t\treturn fmt.Errorf(\"cannot stat %s: %w\", p, err)\n\t}\n}","typeGuard":null,"tryCatchPattern":"if _, err := os.Stat(configFile); err != nil && !errors.Is(err, fs.ErrNotExist) {\n\tif errors.Is(err, fs.ErrPermission) {\n\t\t// traversal problem in a parent directory, not the file itself\n\t\treturn fmt.Errorf(\"unable to stat config file (check parent dir modes with namei -l): %w\", err)\n\t}\n\treturn fmt.Errorf(\"unable to stat config file: %w\", err)\n}","preventionTips":["Diagnose with namei -l <configFile> to find the exact path component denying traversal","Avoid broken symlinks in the config path from dotfile managers — stat surfaces them here","Ensure every parent directory has execute (x) permission for the running user"],"tags":["config","filesystem","stat","permissions"],"backgroundTag":null,"analyzedSha":"e3970c813d93da1ea84edfca90c289d9afb82242","analyzedAt":"2026-08-15T22:50:54.304Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}