charmbracelet/glow · error

unable to create config file: %w

Error message

unable to create config file: %w

What it means

Still in the config-does-not-exist branch of ensureConfigFile: after the directory is made, os.Create(configFile) opens (and creates) the file for writing the default configuration. This error wraps os.Create failing. The directory was just verified, so failures here are about the file path itself.

Source

Thrown at config_cmd.go:77

		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

  1. Check what is at the path: ls -ld <configFile> — if it is a directory, rename or remove it
  2. Confirm write permission on the parent: touch <configFile> manually to reproduce
  3. Choose a different location via --config
  4. On NFS/root-squash setups, run as the owning user or use a local path

Example fix

# before
$ glow config --config ~/cfg/glow.yml
# Error: unable to create config file: open ~/cfg/glow.yml: is a directory

# after
$ rmdir ~/cfg/glow.yml && glow config --config ~/cfg/glow.yml
Defensive patterns

Strategy: validation

Validate before calling

func canCreateFile(p string) error {
	if fi, err := os.Stat(p); err == nil && fi.IsDir() {
		return fmt.Errorf("%s is a directory; a config file is expected", p)
	}
	f, err := os.OpenFile(p, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0o600)
	if err != nil {
		return fmt.Errorf("cannot create %s: %w", p, err)
	}
	return f.Close() // leave creation to glow
}

Try / catch

if err := ensureConfigFile(); err != nil {
	if strings.Contains(err.Error(), "unable to create config file") && errors.Is(err, os.ErrPermission) {
		// switch to a writable location rather than fighting the mount
		configFile = filepath.Join(os.TempDir(), "glow.yml")
		return ensureConfigFile()
	}
	return err
}

Prevention

When it happens

Trigger: The target path already exists as a directory (os.Create on a directory fails); permission denied on the just-created directory because umask/ACLs block write; filename too long; the filesystem rejects creation (read-only mount, immutable attr); symlink loop at the path.

Common situations: A directory accidentally named glow.yml where the config file should go; strict umask 0777 environments; NFS or network mounts with root-squash when running as root; antivirus/FIM tools blocking file creation.

Related errors


AI-assisted analysis of charmbracelet/glow@e3970c813d (2026-08-15). Data as JSON: /api/errors/e8b54a7f3d18319a. Report an issue: GitHub.