gastownhall/beads · error

hook files removed, but failed to reset beads-managed git co

Error message

hook files removed, but failed to reset beads-managed git config: %w

What it means

After removing hook files, uninstallHooks calls resetHooksPathIfBeadsManaged to unset core.hooksPath (when beads-managed) and beads.role. Per GH#4440, a failure here is surfaced as a hard error rather than a warning, so uninstall does not report success while bd config keys remain.

Source

Thrown at cmd/bd/hooks.go:1381

				return fmt.Errorf("failed to remove %s: %w", hookName, err)
			}
			// Restore backup if exists
			backupPath := hookPath + ".backup"
			if _, err := os.Stat(backupPath); err == nil {
				if err := os.Rename(backupPath, hookPath); err != nil {
					fmt.Fprintf(os.Stderr, "Warning: failed to restore backup for %s: %v\n", hookName, err)
				}
			}
		}
		// Not a bd hook at all — leave it alone
	}

	// Reset beads-managed git config (core.hooksPath, beads.role) now that the
	// hook files themselves are removed. A failure here must not be a
	// scrolling stderr warning — bd hooks uninstall must not report success
	// while beads-managed config is still left behind (GH#4440).
	if err := resetHooksPathIfBeadsManaged(); err != nil {
		return fmt.Errorf("hook files removed, but failed to reset beads-managed git config: %w", err)
	}

	return nil
}

// resetHooksPathIfBeadsManaged unsets core.hooksPath if it points to a
// beads-managed hooks directory (.beads/hooks or .beads-hooks), and unsets
// beads.role. beads.role marks a repo as beads-managed independent of
// core.hooksPath, so it is cleared unconditionally here rather than gated on
// the hooksPath match — otherwise an uninstall that runs after core.hooksPath
// was already cleared (e.g. by `bd doctor --fix`) would leave a stale
// beads.role behind. A key that is already absent is not an error.
func resetHooksPathIfBeadsManaged() error {
	repoRoot, _ := git.GetMainRepoRoot()
	if repoRoot == "" {
		repoRoot = git.GetRepoRoot()
	}
	if repoRoot == "" {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Unset the keys manually: `git config --unset-all core.hooksPath` and `git config --unset-all beads.role`.
  2. Check `git config --get-all beads.role` for duplicates from merges and clean them up.
  3. Fix .git/config permissions or corruption reported in the wrapped message.
  4. Re-run `bd hooks uninstall` to get a clean success.

Example fix

// before
$ bd hooks uninstall
// error: hook files removed, but failed to reset beads-managed git config: beads.role: exit status 5 ...
// after
$ git config --unset-all beads.role
$ bd hooks uninstall   # now succeeds
Defensive patterns

Strategy: try-catch

Validate before calling

out, err := exec.Command("git", "config", "--get-all", "beads.role").Output()
if err == nil && len(strings.Fields(string(out))) > 1 {
    return errors.New("beads.role has multiple values; run git config --unset-all beads.role first")
}

Try / catch

if err := uninstallHooks(); err != nil {
    if strings.Contains(err.Error(), "failed to reset beads-managed git config") {
        exec.Command("git", "config", "--unset-all", "beads.role").Run()
        exec.Command("git", "config", "--unset-all", "core.hooksPath").Run()
    }
    return err
}

Prevention

When it happens

Trigger: `bd hooks uninstall` -> resetHooksPathIfBeadsManaged returns an error from `git config --unset core.hooksPath` or `git config --unset beads.role` (unwritable config, ambiguous multi-valued key, config corruption), and uninstallHooks wraps it.

Common situations: Duplicated beads.role from a bad merge or hand edit (git unset refuses multiple values); read-only .git/config in CI; corrupted config file; running under a user lacking write access.

Related errors


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