gastownhall/beads · error

failed to create planning repo: %w

Error message

failed to create planning repo: %w

What it means

Wraps an error from os.MkdirAll(planningPath, 0750) when creating the ~/.beads-planning directory in autoConfigureForkContributor. Thrown only when the planning directory does not yet exist and its creation fails (it is not thrown when the directory already exists).

Source

Thrown at cmd/bd/init_contributor.go:315

				fmt.Printf("\n  %s Fork detected (upstream: %s)\n", ui.RenderWarn("⚠"), upstreamURL)
				fmt.Printf("    Contributor routing configured via config.yaml → %s\n", yamlVal)
				fmt.Printf("    Skipping auto-setup. To reconfigure: bd init --contributor\n")
			}
			return nil
		}
	}

	homeDir, err := os.UserHomeDir()
	if err != nil {
		return fmt.Errorf("failed to get home directory: %w", err)
	}
	planningPath := filepath.Join(homeDir, ".beads-planning")

	createdPlanning := false
	if _, err := os.Stat(planningPath); os.IsNotExist(err) {
		createdPlanning = true
		if err := os.MkdirAll(planningPath, 0750); err != nil {
			return fmt.Errorf("failed to create planning repo: %w", err)
		}
		gitInit := exec.Command("git", "init")
		gitInit.Dir = planningPath
		if err := gitInit.Run(); err != nil {
			return fmt.Errorf("failed to init git in planning repo: %w", err)
		}
		planningBeadsDir := filepath.Join(planningPath, ".beads")
		if err := os.MkdirAll(planningBeadsDir, 0750); err != nil {
			return fmt.Errorf("failed to create .beads in planning repo: %w", err)
		}
		// Initialize the planning Dolt schema so commands like bd migrate-personal
		// can open the store immediately without hitting an uninitialized DB.
		// Non-fatal: no-CGO and server-mode builds skip this silently; the schema
		// initializes on first use once a Dolt server is running for that path.
		if planningStore, storeErr := newDoltStoreFromConfig(ctx, planningBeadsDir); storeErr == nil {
			_ = planningStore.Close()
		}
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check what exists at $HOME/.beads-planning; remove/rename it if it is a regular file blocking mkdir
  2. Ensure $HOME exists and is writable (ls -ld $HOME)
  3. Free disk space if the filesystem is full
  4. Create the directory manually (mkdir -p ~/.beads-planning) and re-run setup

Example fix

// before
$ ls -ld ~/.beads-planning
-rw-r--r-- 1 user user 0 .beads-planning   # a file, not a dir
// after
$ rm ~/.beads-planning && mkdir -p ~/.beads-planning && bd init --contributor
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check the planning path before setup
p := filepath.Join(home, ".beads-planning")
if fi, err := os.Stat(p); err == nil && !fi.IsDir() {
	return fmt.Errorf("%s exists but is not a directory; remove it first", p)
}
if err := os.MkdirAll(p, 0750); err != nil {
	return fmt.Errorf("cannot create planning dir: %w", err)
}

Try / catch

if err := autoConfigureForkContributor(ctx, store, ...); err != nil {
	if strings.Contains(err.Error(), "failed to create planning repo") {
		fmt.Fprintln(os.Stderr, "Check ~/.beads-planning for a blocking file, and HOME writability")
	}
	return err
}

Prevention

When it happens

Trigger: ~/.beads-planning does not exist and os.MkdirAll fails — e.g. HOME points somewhere unwritable, a non-directory file named .beads-planning exists in the way, or an intermediate path component is not a directory (ENOTDIR) or permission is denied.

Common situations: HOME set to a read-only or nonexistent path; stale file ~/.beads-planning that is a regular file; full disk; restrictive umask/permissions on the home directory.

Related errors


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