gastownhall/beads · error

create beads dir: %w

Error message

create beads dir: %w

What it means

SaveUserRecipe ensures the .beads directory exists with MkdirAll before writing recipes.toml; if directory creation fails (an OS-level error), it is wrapped and the save is aborted.

Source

Thrown at internal/recipes/recipes.go:244

		}
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("read recipes.toml: %w", err)
	}

	if userRecipes.Recipes == nil {
		userRecipes.Recipes = make(map[string]Recipe)
	}

	// Add/update the recipe
	userRecipes.Recipes[name] = Recipe{
		Name: name,
		Path: path,
		Type: TypeFile,
	}

	// Ensure directory exists
	if err := os.MkdirAll(beadsDir, 0o700); err != nil {
		return fmt.Errorf("create beads dir: %w", err)
	}

	// Write back
	f, err := os.Create(recipesPath) // #nosec G304 -- path is constructed from validated beadsDir
	if err != nil {
		return fmt.Errorf("create recipes.toml: %w", err)
	}
	defer f.Close()

	encoder := toml.NewEncoder(f)
	if err := encoder.Encode(userRecipes); err != nil {
		return fmt.Errorf("encode recipes.toml: %w", err)
	}

	return nil
}

// ListRecipeNames returns sorted list of all recipe names.

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check that no file named `.beads` (without trailing slash) conflicts: `ls -la` and remove/rename it
  2. Verify write permission on the parent directory
  3. Check disk space / read-only mount (`mount`, `df -h`)
  4. Confirm the beadsDir is resolving where you expect (HOME / --beads-dir flag)

Example fix

// before
.beads is a regular file
// after
rm .beads && mkdir -p .beads
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the beads dir path is creatable before saving
if info, err := os.Stat(beadsDir); err == nil && !info.IsDir() {
	return fmt.Errorf("%s exists but is not a directory", beadsDir)
}
if err := unix.Access(filepath.Dir(beadsDir), unix.W_OK); err != nil {
	return fmt.Errorf("parent dir not writable: %v", err)
}

Try / catch

if err := SaveUserRecipe(ctx, beadsDir, recipe); err != nil {
	if strings.HasPrefix(err.Error(), "create beads dir") {
		os.MkdirAll(filepath.Dir(beadsDir), 0o755) // attempt repair at a higher level
		return err
	}
	return err
}

Prevention

When it happens

Trigger: os.MkdirAll(beadsDir, 0o700) fails because a parent path component is a file, permission is denied on the parent, or the filesystem is read-only.

Common situations: A regular file named .beads exists in the project root, the project directory is read-only, or HOME is misconfigured so the beads dir resolves to an unwritable path.

Related errors


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