air-verse/air · error

failed to write to %s: %w

Error message

failed to write to %s: %w

What it means

After marshaling, writeDefaultConfig writes the schema header plus config content to the created file; a failed file.Write is wrapped as 'failed to write to %s' with the path (.air.toml) and cause. Disk full, I/O errors, or a closed/invalid handle typically trigger it.

Source

Thrown at runner/config.go:372

	if err != nil {
		return "", fmt.Errorf("failed to create a new configuration: %w", err)
	}
	defer file.Close()

	config := defaultConfigBase()
	setEntrypointFromBin(&config)
	addPlatformOverridesForInit(&config, runtime.GOOS)
	configFile, err := toml.Marshal(config)
	if err != nil {
		return "", fmt.Errorf("failed to marshal the default configuration: %w", err)
	}

	headers := []byte(schemaHeader + "\n\n")
	content := append(headers, configFile...)

	_, err = file.Write(content)
	if err != nil {
		return "", fmt.Errorf("failed to write to %s: %w", dftTOML, err)
	}

	return dftTOML, nil
}

// defaultPathConfig loads `.air.toml` or `.config/air.toml` when present.
// The bool is true when a config file was loaded, false when defaults are returned.
func defaultPathConfig() (*Config, bool, error) {
	// when path is blank, first find `.air.toml` in `air_wd` and current working directory or .config/air.toml, if not found, use defaults
	for _, name := range []string{dftTOML, cfgTOML} {
		cfg, err := readConfByName(name)
		if err == nil {
			return cfg, true, nil
		}
		// If the config file exists but failed to parse, report the error
		// Only use defaults if no config file exists
		if !os.IsNotExist(err) {
			return nil, false, fmt.Errorf("failed to parse %s: %w", name, err)

View on GitHub (pinned to 71ea1dee05)

Solutions

  1. Free disk space / check quota: `df -h .`
  2. Retry air init after fixing storage
  3. Check the wrapped cause (%w) for the exact errno and address the mount/filesystem

Example fix

// before
air init  # failed to write to .air.toml: no space left on device
// after
df -h .
# free space, then
air init
Defensive patterns

Strategy: retry

Validate before calling

# ensure free space before writing .air.toml
[ "$(df --output=avail -k . | tail -1)" -gt 1024 ] || echo "low disk space"

Try / catch

if _, err := air.Init(); err != nil {
    if strings.Contains(err.Error(), "failed to write to") {
        // inspect the wrapped cause (ENOSPC, EIO, quota)
        log.Fatalf("write failed: %v", errors.Unwrap(err))
        // fix storage, then retry air init
    }
}

Prevention

When it happens

Trigger: file.Write failing during `air init` — disk quota exceeded, ENOSPC, I/O error on a flaky mount, or the file handle becoming invalid.

Common situations: Full disks or quota-limited containers; writing onto a network/EFS mount that dropped; running out of inodes.

Related errors


AI-assisted analysis of air-verse/air@71ea1dee05 (2026-08-31). Data as JSON: /api/errors/d2819be33c79e1d4. Report an issue: GitHub.