gastownhall/beads · error

cannot write default.nix: %v

Error message

cannot write default.nix: %v

What it means

To discover the correct hash, fixNixHash writes a sentinel value (sha256-AAAA...) into default.nix and runs `nix build`, relying on Nix's mismatch error to reveal the real hash. If the probe write with os.WriteFile fails (permissions, read-only filesystem, disk full), this error is returned; a deferred restore also rewrites the original contents.

Source

Thrown at cmd/bd/preflight.go:774

	}
	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 {
			_ = os.WriteFile(nixPath, content, nixPerm)
		}
	}()

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
	defer cancel()
	nixCmd := exec.CommandContext(ctx, "nix", "build", ".#default", "--no-link")
	nixOut, _ := nixCmd.CombinedOutput()

	// Nix prints the correct hash in lines like "got:    sha256-..."
	hashRe := regexp.MustCompile(`got:\s+(sha256-[A-Za-z0-9+/]+=)`)
	m := hashRe.FindSubmatch(nixOut)
	if m == nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Make the file writable: `chmod u+w default.nix` or take ownership `sudo chown $USER default.nix`
  2. Re-run in a writable checkout (clone fresh or unset the read-only flag on the workspace)
  3. If the filesystem is read-only, run `bd fix` from a writable copy of the repo

Example fix

// before
$ ls -l default.nix  ->  -r--r--r--
cannot write default.nix: open default.nix: permission denied
// after
chmod u+w default.nix && bd fix
Defensive patterns

Strategy: validation

Validate before calling

[ -w default.nix ] || { echo "default.nix must be writable to auto-fix hash"; exit 1; }

Try / catch

out, err := exec.Command("bd", "fix").CombinedOutput()
if err != nil && strings.Contains(string(out), "cannot write default.nix") {
    // chmod u+w / use a writable checkout, then retry
}

Prevention

When it happens

Trigger: os.WriteFile("default.nix", probed, perm) fails during `bd fix` — directory not writable by the current user, filesystem mounted read-only, or insufficient disk space/inodes.

Common situations: Running `bd fix` inside a read-only CI checkout (common with checkout actions that set read-only for cache keys); repo owned by root while bd runs as a normal user; immutable files (chattr +i).

Related errors


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