{"record":{"id":"645ef0b2124832cc","repo":"abhigyanpatwari/GitNexus","slug":"source-branch-name-must-not-start-with-645ef0","errorCode":null,"errorMessage":"${source}: branch name must not start with \"+\".","messagePattern":"(.+?): branch name must not start with \"\\+\"\\.","errorType":"validation","errorClass":"InvalidBranchError","httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/git-ref.ts","lineNumber":81,"sourceCode":"  }\n  assertNoHiddenChars(trimmed, source);\n  if (/\\s/.test(trimmed)) {\n    throw new InvalidBranchError(`${source}: branch name must not contain whitespace.`);\n  }\n  // git ref-name rules (subset): reject characters git itself forbids in refs.\n  if (/[~^:?*[\\\\]/.test(trimmed)) {\n    throw new InvalidBranchError(\n      `${source}: branch name contains characters not allowed in a git ref (~ ^ : ? * [ \\\\).`,\n    );\n  }\n  if (trimmed.startsWith('-')) {\n    throw new InvalidBranchError(`${source}: branch name must not start with \"-\".`);\n  }\n  // Force-refspec prefix (`git fetch origin +main` / `+refs/heads/main:…`).\n  // Rejected here so neither the CLI nor HTTP can pass a force-update refspec\n  // through as a \"branch\" (#3199 review, defense in depth).\n  if (trimmed.startsWith('+')) {\n    throw new InvalidBranchError(`${source}: branch name must not start with \"+\".`);\n  }\n  // The symbolic ref HEAD (case-sensitive). A repo can have a branch named\n  // `head`; git itself treats only `HEAD` as the current-commit alias.\n  if (trimmed === 'HEAD') {\n    throw new InvalidBranchError(`${source}: branch name must not be \"HEAD\".`);\n  }\n  if (trimmed.includes('..')) {\n    throw new InvalidBranchError(`${source}: branch name must not contain \"..\".`);\n  }\n  // The remaining `git check-ref-format` rules. Without these the validator\n  // accepted refs git itself refuses (`feature.lock`, `/feature`, `feature/`,\n  // `feature//next`, `@`, `.hidden`), so the failure surfaced later from the\n  // git subprocess instead of here. No real branch can violate them — git\n  // could not have created one — so nothing that works today starts failing.\n  if (trimmed.endsWith('.lock') || trimmed.split('/').some((part) => part.endsWith('.lock'))) {\n    throw new InvalidBranchError(`${source}: branch name must not end with \".lock\".`);\n  }\n  if (trimmed.startsWith('/') || trimmed.endsWith('/')) {","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/core/git-ref.ts#L63-L99","documentation":"validateBranchName rejects branch names starting with '-' to prevent the name being interpreted as a command-line option when passed to a git subprocess (option-injection defense). A name like '-oProxyCommand=...' would otherwise flow into `git checkout <branch>` style invocations as a flag.","triggerScenarios":"Calling validateBranchName with a value like '-feature', '--depth=1', or a user/HTTP-supplied branch argument that begins with a dash, e.g. `gitnexus analyze --branch -foo`.","commonSituations":"Hand-crafted HTTP requests hitting a /branch endpoint with a dash-prefixed value; CLI scripts interpolating flags into a branch variable; typo where a flag value was omitted so the next flag is consumed as the branch name.","solutions":["Remove the leading dash from the branch value before calling the API.","Check argument order in your CLI/script invocation — a missing flag value may have shifted a '-'-prefixed token into the branch slot.","If the intent was a git option, it is not accepted here; set options via the library's dedicated parameters, never through the branch name."],"exampleFix":"// before\nconst branch = process.argv[4]; // \"--force\"\nvalidateBranchName(branch);\n// after\nconst branch = process.argv[4];\nif (branch) validateBranchName(branch.replace(/^-+/, \"\")); // \"force\"","handlingStrategy":"validation","validationCode":"function startsWithDash(name) { return typeof name === \"string\" && name.startsWith(\"-\"); }\nif (startsWithDash(branch)) throw new Error(\"branch name must not start with '-'\");","typeGuard":"function isOptionSafeBranch(v: unknown): v is string {\n  return typeof v === \"string\" && !v.trim().startsWith(\"-\");\n}","tryCatchPattern":"try {\n  validateBranchName(branch, \"http\");\n} catch (e) {\n  if (e instanceof InvalidBranchError && e.message.includes('start with \"-\"')) {\n    return res.status(400).json({ error: \"branch names must not start with '-'\" });\n  }\n  throw e;\n}","preventionTips":["In CLI parsers, use proper flag parsing (e.g. '--branch=value') so '-'-prefixed tokens never land in a value slot.","For HTTP inputs, reject values starting with '-' before invoking the library.","Never pass git options through a branch-name parameter; use dedicated options.","Log and reject suspicious dash-prefixed values — they often indicate injection attempts."],"tags":["git","security","argument-injection"],"backgroundTag":"invalid-identifier-format","analyzedSha":"ac9a4e9abd8fd3058c070b72c23402a4f887929a","analyzedAt":"2026-09-15T23:29:44.066Z","contentChangedAt":"2026-09-15T23:29:44.066Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}