abhigyanpatwari/GitNexus · error · Error

--branch "${options.branch}" does not match the checked-out

Error message

--branch "${options.branch}" does not match the checked-out branch "${checkedOutBranch}". Check out "${options.branch}" before indexing it, or omit --branch to index the current branch.

What it means

Thrown by the analyze command when the user passes --branch <X> but the repository's currently checked-out branch is <Y> (X != Y). Analyze indexes the working tree content, not an arbitrary git ref; labeling a different branch's content with the wrong branch name would corrupt the branch slot in the index (#2106). The check compares the sanitized auto-detected branch (getCurrentBranch + sanitizeDetectedBranch) against the explicit --branch value. Detached HEAD and non-git repos (checkedOutBranch === null) still allow an explicit label since there's no mismatch to detect.

Source

Thrown at gitnexus/src/core/run-analyze.ts:959

  // `storagePath` is ALWAYS the flat `.gitnexus` — content-addressed caches
  // (parse-cache, parsedfile-store) and kuzu-migration cleanup live there and
  // are shared across branches (#2106 KTD7).
  const { storagePath } = getStoragePaths(repoPath);
  const repoHasGit = hasGitDir(repoPath);
  const currentCommit = repoHasGit ? getCurrentCommit(repoPath) : '';
  // Normalize the auto-detected branch the same way an explicit `--branch` is
  // validated (#2106 R1): a git ref the branch-name rules forbid becomes `null`
  // → the flat slot, matching that a later `--branch <that-ref>` query would
  // also be rejected. A normal ref round-trips index-time/query-time labels.
  const checkedOutBranch = repoHasGit
    ? (sanitizeDetectedBranch(getCurrentBranch(repoPath)) ?? null)
    : null;
  // Analyze indexes the working tree, not an arbitrary ref. An explicit
  // `--branch X` while a DIFFERENT branch Y is checked out would write Y's
  // content into X's slot, corrupting X (#2106). Refuse the mismatch. Detached
  // HEAD / non-git (checkedOutBranch === null) still allow an explicit label.
  if (options.branch && checkedOutBranch && options.branch !== checkedOutBranch) {
    throw new Error(
      `--branch "${options.branch}" does not match the checked-out branch "${checkedOutBranch}". ` +
        `Check out "${options.branch}" before indexing it, or omit --branch to index the current branch.`,
    );
  }
  const branchLabel = options.branch ?? checkedOutBranch;
  const placement = options.branch ? await resolveBranchPlacement(repoPath, branchLabel) : {};
  const { lbugPath, metaPath } = getStoragePaths(repoPath, placement.branch);
  return {
    storagePath,
    repoHasGit,
    currentCommit,
    checkedOutBranch,
    branchLabel,
    placement,
    lbugPath,
    metaPath,
    metaDir: path.dirname(metaPath),
  };

View on GitHub (pinned to d540b00184)

Solutions

  1. Check out the target branch first: `git checkout <branch-name>`, then run `gitnexus analyze --branch <branch-name>`
  2. Omit --branch entirely to index the current branch: `gitnexus analyze` — it auto-detects and labels with the checked-out branch
  3. Verify the current branch with `git branch --show-current` before passing --branch
  4. If you want to index a different branch without switching, use git worktree to create a separate working tree

Example fix

# before — on develop, trying to index as main
git checkout develop
gitnexus analyze --branch main  # ERROR
# after — check out the target branch first
git checkout main
gitnexus analyze --branch main  # OK
# or omit --branch entirely
gitnexus analyze  # auto-detects current branch
Defensive patterns

Strategy: validation

Validate before calling

// Verify the branch matches before calling analyze
import { execSync } from 'child_process';
function getCheckedOutBranch(repoPath: string): string | null {
  try {
    return execSync('git branch --show-current', { cwd: repoPath, encoding: 'utf8' }).trim();
  } catch {
    return null; // non-git or detached HEAD
  }
}
// Before calling analyze with --branch:
const current = getCheckedOutBranch(repoPath);
if (options.branch && current && options.branch !== current) {
  throw new Error(`Checkout ${options.branch} first, or omit --branch to index ${current}`);
}

Try / catch

try {
  await runAnalyze(repoPath, options);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('--branch')) {
    // Branch mismatch — guide user to checkout or omit --branch
    console.error(e.message);
  }
  throw e;
}

Prevention

When it happens

Trigger: Running `gitnexus analyze --branch main` while the repo is checked out on `develop`; running `gitnexus analyze --branch feature/x` while on `main`. The mismatch is detected by comparing the explicit flag against the sanitized git-detected branch name. This prevents writing develop's file contents into main's index slot.

Common situations: A developer working on a feature branch who wants to index it but passes the wrong --branch name; CI that checks out a PR branch but passes the base branch name to --branch; muscle memory from a previous branch switch that hasn't happened yet; confusion about whether --branch checks out the branch (it doesn't — it only labels the index slot).

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/463824457b95c5f1. Report an issue: GitHub.