abhigyanpatwari/GitNexus · error

Branch "${branch}" is not indexed for "${handle.name}". Inde

Error message

Branch "${branch}" is not indexed for "${handle.name}". Indexed branches: ${available}. The workspace index follows the checked-out branch — check out "${branch}" and re-run: gitnexus analyze (add --branch ${branch} while it is checked out to pin a separate sub-index).

What it means

applyBranchScope could not point the resolved handle at the requested branch: no sub-index exists for it and it is not the flat workspace slot's recorded branch. The flat slot's label is read from authoritative on-disk meta (never a stale cached label, #2364), the error lists the branches that ARE indexed, and — because post-#2354 `analyze --branch <X>` refuses to run unless X is checked out — the guidance leads with checking out the branch.

Source

Thrown at gitnexus/src/mcp/local/local-backend.ts:1953

    // Every miss refreshes once before erroring: newly-pinned branches and
    // restamped labels the cached handle predates become resolvable on the
    // caller's next attempt (the cache otherwise only refreshes on repo-
    // resolution misses and list_repos).
    await refreshOnce();

    // The flat slot's label comes from the authoritative meta when readable —
    // never echo a cached label the meta just contradicted (a "not indexed:
    // main / indexed: main" self-contradiction). Cached summaries may still
    // lag; they are a hint, not a promise.
    const flatLabel = flatMeta?.branch ?? handle.branch;
    const indexed = [flatLabel, ...(handle.branches?.map((b) => b.branch) ?? [])].filter(
      (b) => Boolean(b) && b !== branch,
    );
    const available = indexed.length > 0 ? indexed.join(', ') : '(workspace only)';
    // Post-#2354 a bare `analyze --branch <X>` refuses to run unless X is
    // checked out, so the guidance must lead with the checkout (#2364 F6).
    throw new Error(
      `Branch "${branch}" is not indexed for "${handle.name}". ` +
        `Indexed branches: ${available}. The workspace index follows the ` +
        `checked-out branch — check out "${branch}" and re-run: gitnexus analyze ` +
        `(add --branch ${branch} while it is checked out to pin a separate sub-index).`,
    );
  }

  /**
   * Try to resolve a repo from the in-memory cache. Returns null on miss.
   * Throws {@link RegistryAmbiguousTargetError} when `repoParam` matches
   * multiple handles by name and cwd cannot disambiguate (#1658).
   */
  private resolveRepoFromCache(repoParam?: string, allowCwdDefault = false): RepoHandle | null {
    if (this.repos.size === 0) return null;

    if (repoParam) {
      const paramLower = repoParam.toLowerCase();
      const looksLikePath =

View on GitHub (pinned to 0d1aed942f)

Solutions

  1. Check out the branch and re-index: `git checkout feature-x && gitnexus analyze` — the workspace index follows the checked-out branch.
  2. To keep a separate pinned sub-index, check the branch out first, then run `gitnexus analyze --branch feature-x` while it is checked out.
  3. Or drop the branch parameter to query the current workspace index.
  4. Verify what is indexed via the error's 'Indexed branches:' list or gitnexus status before retrying.

Example fix

# before: branch never indexed
{"tool": "impact", "args": {"target": "login", "repo": "myrepo", "branch": "feature-x"}}
# → Branch "feature-x" is not indexed ...

# after: check out, re-analyze, then query
$ git checkout feature-x && gitnexus analyze
{"tool": "impact", "args": {"target": "login", "repo": "myrepo", "branch": "feature-x"}}
# or pin a separate sub-index while checked out:
$ gitnexus analyze --branch feature-x
Defensive patterns

Strategy: validation

Validate before calling

// Before passing branch, confirm it is among the repo's indexed branches
const status = await client.callTool({ name: 'status', arguments: { repo } });
const indexedBranches = [
  status.branch,                          // flat workspace slot (checked-out branch)
  ...(status.branches ?? []).map((b: any) => b.branch),
].filter(Boolean);

function assertIndexedBranch(branch?: string): void {
  if (branch && !indexedBranches.includes(branch)) {
    throw new Error(`branch "${branch}" not indexed for "${repo}". Indexed: ${indexedBranches.join(', ')}`);
  }
}

Try / catch

try {
  return await client.callTool({ name: 'impact', arguments: { ...args, repo, branch } });
} catch (err) {
  if (err instanceof Error && err.message.includes('is not indexed for')) {
    // parse 'Indexed branches:' and either re-target an indexed branch or drop the param
    const indexed = err.message.match(/Indexed branches: ([^.]+)/)?.[1];
    logger.warn(`branch ${branch} missing; indexed: ${indexed} — querying workspace index instead`);
    return client.callTool({ name: 'impact', arguments: { ...args, repo } });
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling a repo-scoped tool with branch: "feature-x" when only main is indexed (the workspace index follows the checked-out branch); passing a branch name whose sub-index was deleted; querying a branch that exists remotely but was never checked out and analyzed locally.

Common situations: Agents diffing review branches by name without a local checkout; worktrees where the flat slot follows a different branch than requested; users assuming remote branches are indexed automatically; sub-indexes cleaned up by registry maintenance.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-08-20). Data as JSON: /api/errors/63037d1a4d74f84a. Report an issue: GitHub.