charmbracelet/glow · error
unable to stat config file: %w
Error message
unable to stat config file: %w
What it means
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.
Source
Thrown at config_cmd.go:85
if _, err := os.Stat(configFile); errors.Is(err, fs.ErrNotExist) {
// File doesn't exist yet, create all necessary directories and
// write the default config file
if err := os.MkdirAll(filepath.Dir(configFile), 0o700); err != nil {
return fmt.Errorf("unable create directory: %w", err)
}
f, err := os.Create(configFile)
if err != nil {
return fmt.Errorf("unable to create config file: %w", err)
}
defer func() { _ = f.Close() }()
if _, err := f.WriteString(defaultConfig); err != nil {
return fmt.Errorf("unable to write config file: %w", err)
}
} else if err != nil { // some other error occurred
return fmt.Errorf("unable to stat config file: %w", err)
}
return nil
}
View on GitHub (pinned to e3970c813d)
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
Example fix
# before $ glow config # Error: unable to stat config file: stat /home/u/.config/glow/glow.yml: permission denied # after $ chmod 755 /home/u/.config && glow config
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-walk the path so a non-NotExist stat failure is caught with context
func probeConfigPath(p string) error {
_, err := os.Stat(p)
switch {
case err == nil, errors.Is(err, fs.ErrNotExist):
return nil
case errors.Is(err, fs.ErrPermission):
return fmt.Errorf("cannot traverse to %s: fix mode/ownership on a parent dir", p)
default:
return fmt.Errorf("cannot stat %s: %w", p, err)
}
} Try / catch
if _, err := os.Stat(configFile); err != nil && !errors.Is(err, fs.ErrNotExist) {
if errors.Is(err, fs.ErrPermission) {
// traversal problem in a parent directory, not the file itself
return fmt.Errorf("unable to stat config file (check parent dir modes with namei -l): %w", err)
}
return fmt.Errorf("unable to stat config file: %w", err)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- could not write configuration file: %w
- unable create directory: %w
- unable to create config file: %w
- unable to write config file: %w
- specified style does not exist: %s
AI-assisted analysis of charmbracelet/glow@e3970c813d (2026-08-15).
Data as JSON: /api/errors/825302d946bebe27.
Report an issue: GitHub.