{"record":{"id":"49e00664f3996d6b","repo":"paperclipai/paperclip","slug":"invalid-branch-name-branchname-extractexec","errorCode":null,"errorMessage":"Invalid branch name \"${branchName}\": ${extractExecSyncErrorMessage(error) ?? String(error)}","messagePattern":"Invalid branch name \"(.+?)\": (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/worktree.ts","lineNumber":636,"sourceCode":"    }).trim();\n    return nonEmpty(value);\n  } catch {\n    return null;\n  }\n}\n\nfunction validateGitBranchName(cwd: string, branchName: string): string {\n  const value = nonEmpty(branchName);\n  if (!value) {\n    throw new Error(\"Branch name is required.\");\n  }\n  try {\n    execFileSync(\"git\", [\"check-ref-format\", \"--branch\", value], {\n      cwd,\n      stdio: [\"ignore\", \"pipe\", \"pipe\"],\n    });\n  } catch (error) {\n    throw new Error(`Invalid branch name \"${branchName}\": ${extractExecSyncErrorMessage(error) ?? String(error)}`);\n  }\n  return value;\n}\n\nfunction isPrimaryGitWorktree(cwd: string): boolean {\n  const workspace = detectGitWorkspaceInfo(cwd);\n  return Boolean(workspace && workspace.gitDir === workspace.commonDir);\n}\n\nfunction resolvePrimaryGitRepoRoot(cwd: string): string {\n  const workspace = detectGitWorkspaceInfo(cwd);\n  if (!workspace) {\n    throw new Error(\"Current directory is not inside a git repository.\");\n  }\n  if (workspace.gitDir === workspace.commonDir) {\n    return workspace.root;\n  }\n  return path.resolve(workspace.commonDir, \"..\");","sourceCodeStart":618,"sourceCodeEnd":654,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/worktree.ts#L618-L654","documentation":"Thrown by validateGitBranchName when `git check-ref-format --branch <value>` exits non-zero, meaning git itself rejected the proposed branch name as malformed or reserved. The error message embeds git's stderr so the exact rule violation is visible.","triggerScenarios":"Passing a branch name that violates git ref-format rules: contains '..' or ' ', has a trailing .lock/.dot, uses control characters, starts with '-' or '.', contains '~', '^', ':', '?', '*', '[', '\\', or equals '@{'; or a name like 'HEAD' that is reserved.","commonSituations":"Auto-derived branch names from issue titles or file paths containing forbidden characters; copy-paste introducing spaces or special chars; names ending in '.lock' colliding with lockfile refs; very long names exceeding git limits.","solutions":["Sanitize the proposed branch name (replace [^A-Za-z0-9._-] with '-') before validation.","Pick a branch name manually that obeys git ref-format rules.","Use resolveRepairWorktreeDirName's normalization logic on the input before validation if a safe slug is acceptable.","Read the embedded git error text to identify the specific forbidden character/pattern and remove it."],"exampleFix":"// before\nconst branch = issueTitle; // \"fix: handle ~ special chars\"\n// after\nconst branch = issueTitle.replace(/[^A-Za-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '');","handlingStrategy":"validation","validationCode":"function sanitizeBranchName(raw: string): string {\n  return raw.replace(/[^A-Za-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '').replace(/\\.lock$/i, '-lock');\n}","typeGuard":"function isValidGitBranch(name: string): boolean {\n  try {\n    execFileSync('git', ['check-ref-format', '--branch', name], { stdio: 'ignore' });\n    return true;\n  } catch { return false; }\n}","tryCatchPattern":"try {\n  validateGitBranchName(repoRoot, branch);\n} catch (e) {\n  if (/Invalid branch name/.test((e as Error).message)) branch = sanitizeBranchName(branch);\n  else throw e;\n}","preventionTips":["Slugify user-derived names before validation.","Avoid '.lock' suffixes and git metacharacters.","Test branch derivation against reserved names like HEAD."],"tags":["git","worktree","branch","validation"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}