gastownhall/beads · error
cannot read default.nix: %v
Error message
cannot read default.nix: %v
What it means
After stat'ing default.nix, fixNixHash reads its contents with os.ReadFile to locate the vendorHash assignment. If the file exists but cannot be read (permission denied, I/O error, or it is a directory named default.nix), this error wraps the os error and aborts the fix.
Source
Thrown at cmd/bd/preflight.go:761
if _, err := exec.LookPath("nix"); err != nil {
return false, "", "", fmt.Errorf(
"nix not found in PATH\n Manual fix:\n" +
" 1. Edit default.nix: set vendorHash = \"sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\"\n" +
" 2. Run: nix build .#default\n" +
" 3. Copy the 'got:' hash from the error into default.nix",
)
}
nixPath := "default.nix"
nixInfo, err := os.Stat(nixPath)
if err != nil {
return false, "", "", fmt.Errorf("cannot stat default.nix: %v", err)
}
nixPerm := nixInfo.Mode().Perm()
content, err := os.ReadFile(nixPath)
if err != nil {
return false, "", "", fmt.Errorf("cannot read default.nix: %v", err)
}
re := regexp.MustCompile(`(vendorHash\s*=\s*)"([^"]+)"`)
loc := re.FindSubmatchIndex(content)
if loc == nil {
return false, "", "", fmt.Errorf("vendorHash not found in default.nix")
}
oldHash := string(content[loc[4]:loc[5]])
const sentinel = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
probed := append(append([]byte{}, content[:loc[4]]...), append([]byte(sentinel), content[loc[5]:]...)...)
if err := os.WriteFile(nixPath, probed, nixPerm); err != nil {
return false, "", "", fmt.Errorf("cannot write default.nix: %v", err)
}
restored := false
defer func() {
if !restored {View on GitHub (pinned to 71377f2769)
Solutions
- Check and fix permissions: `chmod u+r default.nix` (and ownership via chown if needed)
- If the path is a directory, remove/rename it and restore the real default.nix from git: `git checkout -- default.nix`
- Retry after fixing any underlying disk/mount error reported in the wrapped message
Example fix
// before -rw------- default.nix (owned by other user) -> cannot read default.nix: ... // after chmod u+r default.nix && bd fix
Defensive patterns
Strategy: validation
Validate before calling
[ -r default.nix ] && [ -f default.nix ] || { echo "default.nix must be a readable file"; exit 1; } Try / catch
out, err := exec.Command("bd", "fix").CombinedOutput()
if err != nil && strings.Contains(string(out), "cannot read default.nix") {
// fix permissions/ownership, then retry
} Prevention
- Commit default.nix with world-readable permissions (644)
- Avoid storing default.nix with restrictive umask in shared workspaces
- Watch for tools that replace default.nix with a directory (artifact collisions)
When it happens
Trigger: os.ReadFile("default.nix") fails during `bd fix` — e.g. file mode denies read for the current user, the file is actually a directory, or a disk/ACL problem prevents reading.
Common situations: default.nix checked in with restrictive permissions (e.g. 0600 owned by another user) in a shared CI workspace; a directory accidentally named default.nix; read-only or corrupted mount.
Related errors
- cannot write default.nix: %v
- cannot update default.nix: %v
- dolt path is not executable
- failed to create backup directory: %w
- failed to create temp file: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/43a8c741ad77927e.
Report an issue: GitHub.