abhigyanpatwari/GitNexus · error · InvalidBranchError
: branch name must not contain "@
Error message
${source}: branch name must not contain "@{". What it means
validateBranchName rejects names containing '@{', which in git ref syntax is the reflog/revision prefix (e.g. '@{1}', 'branch@{yesterday}') and can never be part of a real branch name. Throwing here keeps reflog expressions out of a branch-name parameter, per git check-ref-format rules.
Solutions
- Pass a plain branch name; resolve the reflog/upstream expression first, e.g. `git rev-parse --abbrev-ref main@{u}`.
- Use the library's revision/commit options for '@{...}' expressions instead of the branch parameter.
- Strip or reject '@{' at your input boundary before invoking the API.
Example fix
// before
validateBranchName("main@{u}");
// after
const branch = execSync("git rev-parse --abbrev-ref main@{u}").toString().trim(); // e.g. "origin/main"
validateBranchName(branch); Defensive patterns
Strategy: validation
Validate before calling
function hasReflogExpr(name) { return typeof name === "string" && name.includes("@{"); }
if (hasReflogExpr(branch)) throw new Error(`'${branch}' is a revision expression, not a branch`); Type guard
function isPlainRef(v: unknown): v is string {
return typeof v === "string" && !v.includes("@{");
} Try / catch
try {
validateBranchName(branch, "cli");
} catch (e) {
if (e instanceof InvalidBranchError && e.message.includes('"@{"')) {
console.error("Resolve @{...} expressions with git rev-parse first.");
process.exitCode = 2;
} else throw e;
} Prevention
- Resolve reflog/upstream syntax ('main@{u}', 'HEAD@{1}') to a concrete ref before passing it.
- Keep revision expressions in revision parameters only.
- Add '@{' to your input-sanitization deny-list for branch fields.
- Educate users that branch parameters accept plain names only.
When it happens
Trigger: Calling validateBranchName with values like 'HEAD@{1}', 'main@{u}', or a revision expression pasted into the branch argument, e.g. `--branch main@{yesterday}`.
Common situations: Users copying reflog queries or upstream shorthand ('@{u}', '@{push}') into a branch field; scripts interpolating `git rev-parse` expressions; docs examples mixing revision syntax with branch parameters.
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
- err.message (InvalidBranchError rethrown as GitNexusRcError…
- : branch name contains characters not allowed in a git ref…
- : branch name is too long (max ).
- : branch name must not be empty.
- : branch name must not be "HEAD".
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/73f7cb0e63881451.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/core/git-ref.ts:109
// 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).`,
);
}
return trimmed;View on GitHub (pinned to ac9a4e9abd)