gastownhall/beads · error

failed to write config.yaml: %w

Error message

failed to write config.yaml: %w

What it means

createConfigYaml writes the bootstrap .beads/config.yaml (rendered from prefix/noDbMode) only if the file does not already exist. If os.WriteFile fails, the error is wrapped as 'failed to write config.yaml: %w'. Called by finalizeSyncedBootstrap during init, so init cannot finish provisioning the workspace config.

Source

Thrown at cmd/bd/init_templates.go:21

import (
	"fmt"
	"os"
	"path/filepath"
)

// createConfigYaml creates the config.yaml template in the specified directory
// In --no-db mode, the prefix is saved here since there's no database to store it.
func createConfigYaml(beadsDir string, noDbMode bool, prefix string) error {
	configYamlPath := filepath.Join(beadsDir, "config.yaml")

	// Skip if already exists
	if _, err := os.Stat(configYamlPath); err == nil {
		return nil
	}

	body := renderInitConfigYAML(prefix, noDbMode)
	if err := os.WriteFile(configYamlPath, body, 0600); err != nil {
		return fmt.Errorf("failed to write config.yaml: %w", err)
	}

	return nil
}

func renderInitConfigYAML(prefix string, noDbMode bool) []byte {
	noDbLine := "# no-db: false"
	if noDbMode {
		noDbLine = "no-db: true  # JSONL-only mode, no database"
	}

	prefixLine := "# issue-prefix: \"\""
	if noDbMode && prefix != "" {
		prefixLine = fmt.Sprintf("issue-prefix: %q", prefix)
	}

	body := fmt.Sprintf(`# Beads Configuration File
# This file configures default behavior for all bd commands in this repository

View on GitHub (pinned to 71377f2769)

Solutions

  1. Ensure the parent directory exists and is writable (mkdir -p .beads; chown if needed)
  2. Check whether config.yaml path is actually a directory or locked; remove/fix it
  3. Free disk space if the disk is full
  4. Re-run `bd init` after fixing permissions

Example fix

// before
$ bd init
failed to write config.yaml: open /repo/.beads/config.yaml: permission denied
// after
$ mkdir -p .beads && chmod u+w .beads
$ bd init
Defensive patterns

Strategy: validation

Validate before calling

dir := filepath.Join(beadsDir, "config.yaml")
if fi, err := os.Stat(filepath.Dir(dir)); err != nil || !fi.IsDir() {
    return fmt.Errorf(".beads directory missing or invalid")
}
if fi, err := os.Stat(dir); err == nil && fi.IsDir() {
    return fmt.Errorf("config.yaml path is a directory")
}

Try / catch

if err := createConfigYaml(prefix, noDbMode); err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) {
        log.Printf("config write blocked at %s: %v", pe.Path, pe.Err)
    }
    return err
}

Prevention

When it happens

Trigger: Running `bd init` (synced bootstrap path) when os.WriteFile on the config.yaml path fails: parent directory missing, permission denied, path is a directory, read-only filesystem, or disk full.

Common situations: .beads directory not created or wrong owner; running under a user without write access to the repo; .beads/config.yaml exists as a directory (odd checkouts); CI runs on a read-only checkout.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/46d02569baaa4ef6. Report an issue: GitHub.