gastownhall/beads · error

failed to untrack redirect file: %w

Error message

failed to untrack redirect file: %w

What it means

FixRedirectTracking untracks .beads/redirect from git (the redirect file is machine-local and must not be committed) using `git rm --cached <redirectPath>`. This error wraps the failure of that command. Note cmd.Run() only surfaces exec exit-status errors, so the cause is typically a git-level failure rather than a Go problem.

Source

Thrown at cmd/bd/doctor/gitignore.go:343

func FixRedirectTracking(repoPath string) error {
	redirectPath := filepath.Join(repoPath, ".beads", "redirect")

	// Check if file is actually tracked first
	cmd := exec.Command("git", "ls-files", redirectPath) // #nosec G204 - args are hardcoded paths
	output, err := cmd.Output()
	if err != nil {
		return nil // Not a git repo, nothing to do
	}

	trackedPath := strings.TrimSpace(string(output))
	if trackedPath == "" {
		return nil // Not tracked, nothing to do
	}

	// Untrack the file (keeps the local copy)
	cmd = exec.Command("git", "rm", "--cached", redirectPath) // #nosec G204 - args are hardcoded paths
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("failed to untrack redirect file: %w", err)
	}

	return nil
}

// parseRedirectTarget extracts the first non-comment, non-empty redirect target.
// It also strips a UTF-8 BOM if present.
func parseRedirectTarget(data []byte) string {
	content := strings.TrimSpace(string(data))
	if content == "" {
		return ""
	}

	lines := strings.Split(content, "\n")
	for _, line := range lines {
		line = strings.TrimSpace(line)
		line = strings.TrimPrefix(line, "\ufeff")
		if line == "" || strings.HasPrefix(line, "#") {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Run `git rm --cached .beads/redirect` manually to see git's actual error message
  2. Resolve any in-progress merge/rebase (`git status`, then commit or abort) before retrying `bd doctor --fix`
  3. Ensure the path is tracked as expected: `git ls-files .beads/redirect`; if untracked, nothing needs fixing
  4. Confirm you are inside the git repository that tracks the redirect file (cwd must be within the repo)

Example fix

// before: doctor fails because a merge is in progress
$ bd doctor --fix
failed to untrack redirect file: exit status 1
// after
$ git merge --abort  # or resolve and commit
$ bd doctor --fix
Defensive patterns

Strategy: validation

Validate before calling

const tracked = execSync('git ls-files -- .beads/redirect', { encoding: 'utf8' }).trim();
const status = execSync('git status --porcelain', { encoding: 'utf8' });
if (status.includes('UU') || status.includes('DD')) {
  throw new Error('resolve merge conflicts before running bd doctor --fix');
}
if (!tracked) console.log('.beads/redirect not tracked; nothing to untrack');

Try / catch

try {
  execSync('bd doctor --fix', { stdio: 'inherit' });
} catch (err) {
  if (String(err.stderr).includes('failed to untrack redirect file')) {
    // surface git's own diagnosis
    console.error(execSync('git status --porcelain', { encoding: 'utf8' }));
  }
  throw err;
}

Prevention

When it happens

Trigger: FixRedirectTracking finds the redirect file is tracked by git and runs `git rm --cached redirectPath`; the command exits non-zero — the path is not actually in the index, git refuses mid-merge/rebase, the working tree is dirty in a conflicting state, or the target isn't a git repository.

Common situations: Redirect file was committed before the ignore rule was added and the index state differs from what the check expects; running during an unfinished merge/rebase; .beads/ lives outside the repo root passed to git; git identity/hooks failing in CI.

Related errors


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