gastownhall/beads · error

failed to read user config.yaml: %w

Error message

failed to read user config.yaml: %w

What it means

UnsetUserYamlConfig reads the user-level config.yaml (path from UserConfigYamlPath) to comment out the given key. If ReadFile fails with anything other than not-exists (which is treated as success/no-op), it wraps the error as 'failed to read user config.yaml'.

Source

Thrown at internal/config/yaml_config.go:471

	if err != nil {
		return false
	}
	return shown
}

func UnsetUserYamlConfig(key string) error {
	configPath, err := UserConfigYamlPath()
	if err != nil {
		return err
	}
	normalizedKey := normalizeYamlKey(key)

	content, err := os.ReadFile(configPath) //nolint:gosec // configPath is a validated absolute user config path
	if err != nil {
		if os.IsNotExist(err) {
			return nil
		}
		return fmt.Errorf("failed to read user config.yaml: %w", err)
	}

	newContent := commentOutYamlKey(string(content), normalizedKey)

	// Preserve the owner-private 0600 posture every other user-global writer
	// uses (SetUserYamlConfig, setYamlConfigAtPath, the metrics bootstrap);
	// rewriting at 0644 would relax this shared user config to world-readable.
	if err := os.WriteFile(configPath, []byte(newContent), 0o600); err != nil { //nolint:gosec // configPath is from UserConfigYamlPath
		return fmt.Errorf("failed to write user config.yaml: %w", err)
	}

	return nil
}

func SetUserYamlConfig(key, value string) error {
	if err := validateYamlConfigValue(key, value); err != nil {
		return err
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Fix file permissions: chmod 600 ~/.beads/config.yaml and ensure it is owned by the current user (chown $USER).
  2. If config.yaml is a directory, rename/remove it and recreate as a file.
  3. Check the wrapped %w cause for the underlying errno and resolve it (disk, lock, AV scanner).
  4. If the key was never set, no action needed — a missing file is already treated as success.

Example fix

// before
sudo bd config set metrics.enabled true   # creates root-owned config
bd config unset metrics.enabled            // read fails EACCES
// after
sudo chown $USER ~/.beads/config.yaml
chmod 600 ~/.beads/config.yaml
bd config unset metrics.enabled
Defensive patterns

Strategy: try-catch

Validate before calling

info, err := os.Stat(userConfigPath)
if err == nil {
    if info.IsDir() { return errors.New("user config.yaml is a directory") }
    if err := unix.Access(userConfigPath, unix.R_OK); err != nil {
        return fmt.Errorf("user config.yaml unreadable: %w", err)
    }
}

Try / catch

err := config.UnsetUserYamlConfig(key)
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission) {
    // advise: chown $USER ~/.beads/config.yaml && chmod 600 ...
    return adviseOwnershipFix(pe.Path)
}

Prevention

When it happens

Trigger: Calling UnsetUserYamlConfig(key) when ~/.beads/config.yaml (or the platform equivalent) exists but cannot be read: permission denied, path is a directory, or a transient I/O error. Not-exist returns nil instead.

Common situations: Config file owned by root after running bd with sudo; config.yaml replaced by a directory; antivirus/backup tools locking the file on Windows.

Related errors


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