charmbracelet/glow · error
unable create directory: %w
Error message
unable create directory: %w
What it means
In the branch where the config file does not exist yet (os.Stat returned fs.ErrNotExist), ensureConfigFile first creates the containing directory with os.MkdirAll(dir, 0o700) before writing the default config. This error wraps that MkdirAll failure. Note the 0o700 mode here versus the 0o755 pre-check earlier — both must succeed.
Source
Thrown at config_cmd.go:72
}
func ensureConfigFile() error {
if configFile == "" {
configFile = viper.GetViper().ConfigFileUsed()
if err := os.MkdirAll(filepath.Dir(configFile), 0o755); err != nil { //nolint:gosec
return fmt.Errorf("could not write configuration file: %w", err)
}
}
if ext := path.Ext(configFile); ext != ".yaml" && ext != ".yml" {
return fmt.Errorf("'%s' is not a supported configuration type: use '%s' or '%s'", ext, ".yaml", ".yml")
}
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
- Create the directory manually with correct ownership: mkdir -p ~/.config/glow && chown $USER ~/.config/glow
- Remove anything occupying the path that should be a directory: rm ~/.config/glow (if it is a file)
- Use an alternative writable location: glow config --config /path/with/access/glow.yml
- Free disk space or fix quota if writes fail filesystem-wide
Example fix
# before $ glow config # Error: unable create directory: mkdir /home/u/.config/glow: file exists # after $ rm /home/u/.config/glow && glow config # was a file, now a dir is created
Defensive patterns
Strategy: validation
Validate before calling
func prepNewConfigDir(cfgPath string) error {
dir := filepath.Dir(cfgPath)
if fi, err := os.Stat(dir); err == nil && !fi.IsDir() {
return fmt.Errorf("%s exists but is not a directory", dir)
}
if err := os.MkdirAll(dir, 0o700); err != nil {
return fmt.Errorf("cannot create config dir: %w", err)
}
return nil
} Try / catch
if err := ensureConfigFile(); err != nil {
if strings.Contains(err.Error(), "unable create directory") {
// pre-clear the path: it is a file/symlink squatting on the dir name
if fi, statErr := os.Stat(filepath.Dir(configFile)); statErr == nil && !fi.IsDir() {
_ = os.Remove(filepath.Dir(configFile))
return ensureConfigFile()
}
}
return err
} Prevention
- Ensure ~/.config/glow is a directory owned by the running user before first launch
- In Dockerfiles, pre-create it: RUN mkdir -p /root/.config/glow
- Watch for dotfile managers placing a file (not a symlink) where the directory belongs
When it happens
Trigger: First-run creation where the config directory's parent is unwritable or owned by another user; a path component already existing as a non-directory file; read-only or full filesystem; SELinux/AppArmor denying mkdir in the config location.
Common situations: First launch in a container as non-root with root-owned /home/user; home directory on a full disk quota; ~/.config/glow existing as a file instead of a directory.
Related errors
- could not write configuration file: %w
- unable to create config file: %w
- unable to stat 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/770ca116112499dc.
Report an issue: GitHub.