abhigyanpatwari/GitNexus · error · InvalidBranchError

: branch name must not be the single character "@".

Error message

${source}: branch name must not be the single character "@".

What it means

validateBranchName rejects the single character '@' because git reserves a bare '@' as an alias for HEAD. Since '@' cannot be a real branch name (git's own rule), the validator throws early so callers get a clear InvalidBranchError instead of a git subprocess failure or silent HEAD aliasing.

Solutions

  1. Pass the real branch name; resolve '@' with `git rev-parse --abbrev-ref @` first if you want the current branch.
  2. If you intended a revision shortcut ('@', '@~1'), use the commit/revision parameter, not the branch parameter.
  3. Check string slicing/format code that may have dropped the rest of the branch name.

Example fix

// before
const branch = "@";
validateBranchName(branch);
// after
const branch = execSync("git rev-parse --abbrev-ref @").toString().trim();
validateBranchName(branch);
Defensive patterns

Strategy: validation

Validate before calling

function isBareAt(name) { return typeof name === "string" && name === "@"; }
if (isBareAt(branch)) branch = execSync("git rev-parse --abbrev-ref @").toString().trim();

Type guard

function isNotBareAt(v: unknown): v is string {
  return typeof v === "string" && v !== "@";
}

Try / catch

try {
  validateBranchName(branch, "cli");
} catch (e) {
  if (e instanceof InvalidBranchError && e.message.includes('"@"')) {
    console.error("'@' is git shorthand for HEAD; pass a real branch name.");
    process.exitCode = 2;
  } else throw e;
}

Prevention

When it happens

Trigger: Calling validateBranchName with branch='@', typically from a truncated revision shortcut like '@', '@~1', or a config/env value that collapsed to just '@'.

Common situations: Users typing the git shorthand '@' into a branch field; scripts using `git rev-parse @` output assumptions; templating that lost the rest of the name.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15). Data as JSON: /api/errors/8376ac29920051a6. Report an issue: GitHub.

Appendix: source

Thrown at gitnexus/src/core/git-ref.ts:106

  if (trimmed.includes('..')) {
    throw new InvalidBranchError(`${source}: branch name must not contain "..".`);
  }
  // The remaining `git check-ref-format` rules. Without these the validator
  // accepted refs git itself refuses (`feature.lock`, `/feature`, `feature/`,
  // `feature//next`, `@`, `.hidden`), so the failure surfaced later from the
  // git subprocess instead of here. No real branch can violate them — git
  // could not have created one — so nothing that works today starts failing.
  if (trimmed.endsWith('.lock') || trimmed.split('/').some((part) => part.endsWith('.lock'))) {
    throw new InvalidBranchError(`${source}: branch name must not end with ".lock".`);
  }
  if (trimmed.startsWith('/') || trimmed.endsWith('/')) {
    throw new InvalidBranchError(`${source}: branch name must not start or end with "/".`);
  }
  if (trimmed.includes('//')) {
    throw new InvalidBranchError(`${source}: branch name must not contain consecutive slashes.`);
  }
  if (trimmed === '@') {
    throw new InvalidBranchError(`${source}: branch name must not be the single character "@".`);
  }
  if (trimmed.includes('@{')) {
    throw new InvalidBranchError(`${source}: branch name must not contain "@{".`);
  }
  if (trimmed.endsWith('.') || trimmed.split('/').some((part) => part.startsWith('.'))) {
    throw new InvalidBranchError(
      `${source}: branch name must not end with "." or have a path component starting with ".".`,
    );
  }
  // Git permits a backtick in a ref, but the branch is embedded inside a
  // Markdown inline-code span in the generated AGENTS.md/CLAUDE.md regression
  // example, where a backtick would close the span early and let the rest of
  // the template render as instruction text. Reject it at this single
  // chokepoint so all three tiers (CLI flag, .gitnexusrc, auto-detect via
  // sanitizeDetectedBranch) are covered (#1996 tri-review P1).
  if (trimmed.includes('`')) {
    throw new InvalidBranchError(
      `${source}: branch name must not contain a backtick (it would break the generated Markdown).`,

View on GitHub (pinned to ac9a4e9abd)