abhigyanpatwari/GitNexus · warning · GitNexusRcError

: branch name contains characters not allowed in a git ref…

Error message

${source}: branch name contains characters not allowed in a git ref (~ ^ : ? * [ \).

What it means

During a wipe of the DB directory, the contentless `.lock` file survived all unlink retries (HANDLE_RELEASE_PROBE_ATTEMPTS with backoff). The wipe deliberately continues because the lock carries no state and initLbug recreates it; a genuinely held lock will instead surface as the reopen's own lock-busy error. Only surviving data files (dataSurvivors) escalate to LbugWipeError.

Solutions

  1. No action if the subsequent reopen succeeds — the warn documents a deliberate continuation
  2. If reopen fails with lock-busy, find the concurrent process holding the lock and stop it
  3. Keep AV exclusions on the storage directory so unlink retries succeed
  4. Ensure only one wipe/reindex runs against the storage dir at a time
Defensive patterns

Strategy: fallback

Type guard

import { LbugWipeError } from 'gitnexus/dist/core/lbug/lbug-adapter.js';
const isLbugWipeError = (e: unknown): e is LbugWipeError => e instanceof LbugWipeError;

Try / catch

try {
  await wipeLbugDirectory(dbPath);
} catch (e) {
  if (isLbugWipeError(e)) {
    // data files survived (the .lock alone never fails the wipe):
    // stop whatever holds them, then retry the wipe once
    logger.warn(`wipe survivors: ${e.survivors?.join(', ')}`);
    throw e;
  }
  throw e;
}

Prevention

When it happens

Trigger: survivors after the retry loop includes lockPath on Windows or any platform where unlink of the lock is deferred — AV or another process transiently holding the lock file during a wipe-and-reopen flow.

Common situations: Reindex flows that wipe the storage directory; a second GitNexus process or file scanner touching the lock at wipe time; Windows filter drivers deferring deletion. The subsequent open either succeeds (lock was stale) or fails with a lock-busy error that names the real holder.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@52924ef12c (2026-08-20). Data as JSON: /api/errors/af94d88fb5900111. Report an issue: GitHub.

Appendix: source

Thrown at gitnexus/src/cli/analyze-config.ts:177

 * Validate a user-supplied branch name (from CLI or `.gitnexusrc`). Returns the
 * trimmed name or throws {@link GitNexusRcError}. Conservative but accepts the
 * shapes real branches use (`feature/foo-bar`, `release/1.2`, `develop`).
 */
export function validateBranchName(value: string, source: string): string {
  const trimmed = value.trim();
  if (!trimmed) {
    throw new GitNexusRcError(`${source}: branch name must not be empty.`);
  }
  if (trimmed.length > BRANCH_MAX_LENGTH) {
    throw new GitNexusRcError(`${source}: branch name is too long (max ${BRANCH_MAX_LENGTH}).`);
  }
  assertNoHiddenChars(trimmed, source);
  if (/\s/.test(trimmed)) {
    throw new GitNexusRcError(`${source}: branch name must not contain whitespace.`);
  }
  // git ref-name rules (subset): reject characters git itself forbids in refs.
  if (/[~^:?*[\\]/.test(trimmed)) {
    throw new GitNexusRcError(
      `${source}: branch name contains characters not allowed in a git ref (~ ^ : ? * [ \\).`,
    );
  }
  if (trimmed.startsWith('-')) {
    throw new GitNexusRcError(`${source}: branch name must not start with "-".`);
  }
  if (trimmed.includes('..')) {
    throw new GitNexusRcError(`${source}: branch name must not contain "..".`);
  }
  // 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 GitNexusRcError(
      `${source}: branch name must not contain a backtick (it would break the generated Markdown).`,

View on GitHub (pinned to 52924ef12c)