gastownhall/beads · error

cannot read cmd/bd/version.go: %v

Error message

cannot read cmd/bd/version.go: %v

What it means

fixVersionSync keeps cmd/bd/version.go's Version constant in sync with the version in default.nix (default.nix is the source of truth). Its first step os.Stat's cmd/bd/version.go to capture permissions; if the stat fails the file is treated as unreadable and this error (with the message 'cannot read') wraps the os error.

Source

Thrown at cmd/bd/preflight.go:828

		restored = true
		return false, oldHash, newHash, nil
	}

	updated := append(append([]byte{}, content[:loc[4]]...), append([]byte(newHash), content[loc[5]:]...)...)
	if err := os.WriteFile(nixPath, updated, nixPerm); err != nil {
		return false, oldHash, newHash, fmt.Errorf("cannot update default.nix: %v", err)
	}
	restored = true
	return true, oldHash, newHash, nil
}

// fixVersionSync updates cmd/bd/version.go to match the version in default.nix.
// default.nix is the source of truth. Returns (fixed, oldVersion, newVersion, err).
func fixVersionSync() (bool, string, string, error) {
	vgoPath := "cmd/bd/version.go"
	vgoInfo, err := os.Stat(vgoPath)
	if err != nil {
		return false, "", "", fmt.Errorf("cannot read cmd/bd/version.go: %v", err)
	}
	vgoPerm := vgoInfo.Mode().Perm()

	vgoContent, err := os.ReadFile(vgoPath)
	if err != nil {
		return false, "", "", fmt.Errorf("cannot read cmd/bd/version.go: %v", err)
	}

	vgoRe := regexp.MustCompile(`(Version\s*=\s*)"([^"]+)"`)
	vgoLoc := vgoRe.FindSubmatchIndex(vgoContent)
	if vgoLoc == nil {
		return false, "", "", fmt.Errorf("cannot parse Version from cmd/bd/version.go")
	}
	oldVersion := string(vgoContent[vgoLoc[4]:vgoLoc[5]])

	nixContent, err := os.ReadFile("default.nix")
	if err != nil {
		// No default.nix — nothing to sync against

View on GitHub (pinned to 71377f2769)

Solutions

  1. Run `bd fix` from the repository root so the relative path cmd/bd/version.go resolves
  2. Verify the file exists: `ls cmd/bd/version.go`; restore from git if deleted (`git checkout -- cmd/bd/version.go`)
  3. Fix directory traversal permissions if the repo tree is not readable by the current user

Example fix

// before
$ cd cmd/bd && bd fix
cannot read cmd/bd/version.go: stat cmd/bd/version.go: no such file or directory
// after
$ cd /path/to/repo && bd fix
Defensive patterns

Strategy: validation

Validate before calling

[ -f cmd/bd/version.go ] || { echo "run from repo root; cmd/bd/version.go missing"; exit 1; }

Try / catch

out, err := exec.Command("bd", "fix").CombinedOutput()
if err != nil && strings.Contains(string(out), "cannot read cmd/bd/version.go") {
    // cd to repo root or restore version.go, then retry
}

Prevention

When it happens

Trigger: Running `bd fix` from a directory where cmd/bd/version.go does not exist at that relative path (not at repo root), the path is a broken symlink, or directory permissions prevent stat.

Common situations: Executing `bd fix` from a subdirectory (e.g. cmd/bd itself) so the relative path cmd/bd/version.go doesn't resolve; version.go renamed or removed during refactors; broken symlink in a copied workspace.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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