charmbracelet/glow · error

unable to write config file: %w

Error message

unable to write config file: %w

What it means

The final step of first-run config creation: the freshly created file (kept open with a deferred Close) is filled with defaultConfig via f.WriteString. This error wraps a short or failed write. Creation succeeded, so this is about writing bytes to the open file.

Source

Thrown at config_cmd.go:82

	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 space: df -h ~/.config and quotas: quota -s
  2. Retry the command — transient NFS/I/O hiccups often clear
  3. Free space or point --config at a volume with room
  4. Verify no security agent is holding/locking the file (lsof <configFile>)

Example fix

# before
$ glow config
# Error: unable to write config file: write /home/u/.config/glow/glow.yml: no space left on device

# after
$ df -h /home && rm -rf ~/.cache/tmp-big-files && glow config
Defensive patterns

Strategy: try-catch

Validate before calling

// fail fast when the target volume has no room for the ~1KB default config
var stat syscall.Statfs_t
if err := syscall.Statfs(filepath.Dir(configFile), &stat); err == nil {
	if stat.Bavail*uint64(stat.Bsize) < 64<<10 {
		return errors.New("less than 64KiB free for the config volume")
	}
}

Try / catch

if _, err := f.WriteString(defaultConfig); err != nil {
	// surface ENOSPC distinctly — the file was created but is incomplete
	if errors.Is(err, syscall.ENOSPC) {
		_ = f.Close()
		_ = os.Remove(configFile) // avoid leaving a truncated config behind
		return fmt.Errorf("disk full while writing config; freed space? rerun 'glow config': %w", err)
	}
	return fmt.Errorf("unable to write config file: %w", err)
}

Prevention

When it happens

Trigger: Disk full or quota exceeded between os.Create and the write; filesystem I/O error (NFS stale handle, dying disk); the file being made read-only by a concurrent process or ACL between create and write; sandboxing blocking writes to the config area.

Common situations: Full home partitions on shared machines; container layers with size limits (overlay quota); security software locking newly created files; flaky network mounts.

Related errors


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