{"record":{"id":"83f60afafb7386fb","repo":"paperclipai/paperclip","slug":"worktree-name-must-contain-only-letters-numbers","errorCode":null,"errorMessage":"Worktree name must contain only letters, numbers, dots, underscores, or dashes.","messagePattern":"Worktree name must contain only letters, numbers, dots, underscores, or dashes\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/src/commands/worktree.ts","lineNumber":270,"sourceCode":"): string {\n  return [\n    `disabled timer heartbeats: ${summary.disabledTimerHeartbeats}`,\n    `reset running agents: ${summary.resetRunningAgents}`,\n    `quarantined in-progress issues: ${summary.quarantinedInProgressIssues}`,\n    `unassigned todo issues: ${summary.unassignedTodoIssues}`,\n    `unassigned review issues: ${summary.unassignedReviewIssues}`,\n  ].join(\", \");\n}\n\nconst WORKTREE_NAME_PREFIX = \"paperclip-\";\n\nfunction resolveWorktreeMakeName(name: string): string {\n  const value = nonEmpty(name);\n  if (!value) {\n    throw new Error(\"Worktree name is required.\");\n  }\n  if (!/^[A-Za-z0-9._-]+$/.test(value)) {\n    throw new Error(\n      \"Worktree name must contain only letters, numbers, dots, underscores, or dashes.\",\n    );\n  }\n  return value.startsWith(WORKTREE_NAME_PREFIX) ? value : `${WORKTREE_NAME_PREFIX}${value}`;\n}\n\nfunction resolveWorktreeHome(explicit?: string): string {\n  return explicit ?? process.env.PAPERCLIP_WORKTREES_DIR ?? DEFAULT_WORKTREE_HOME;\n}\n\nfunction resolveWorktreeStartPoint(explicit?: string): string | undefined {\n  return explicit ?? nonEmpty(process.env.PAPERCLIP_WORKTREE_START_POINT) ?? undefined;\n}\n\ntype ConfiguredStorage = {\n  getObject(companyId: string, objectKey: string): Promise<Buffer>;\n  putObject(companyId: string, objectKey: string, body: Buffer, contentType: string): Promise<void>;\n};","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/worktree.ts#L252-L288","documentation":"Thrown by resolveWorktreeMakeName when the trimmed name is non-empty but fails the regex ^[A-Za-z0-9._-]+$. The name becomes a filesystem branch/directory identifier (prefixed with 'paperclip-'), so characters that break git branches or paths — spaces, slashes, colons, shell metacharacters, Unicode — are rejected.","triggerScenarios":"Passing a worktree name containing a space, slash, colon, @, parentheses, emoji, or any non-[A-Za-z0-9._-] character to the make/create flow. E.g. `paperclipai worktree make 'my feature'`, `'feature/xyz'`, `'feat@v2'`.","commonSituations":"Using a descriptive ticket title as the worktree name (contains spaces/slashes). Copy-pasting a branch name with slashes expecting it to work. Non-ASCII characters in the name.","solutions":["Use only letters, numbers, dots, underscores, and dashes: `paperclipai worktree make my-feature`.","Replace spaces with dashes or underscores and strip slashes: 'feat/xyz' -> 'feat-xyz'.","Avoid slashes — this name is a single path/branch segment, not a nested path."],"exampleFix":"# before\npaperclipai worktree make \"feature/xyz branch\"\n# after\npaperclipai worktree make feature-xyz-branch","handlingStrategy":"validation","validationCode":"function sanitizeWorktreeName(raw: string): string | null {\n  const trimmed = raw.trim();\n  if (!trimmed) return null;\n  return /^[A-Za-z0-9._-]+$/.test(trimmed) ? trimmed : trimmed.replace(/[^A-Za-z0-9._-]/g, '-');\n}\n// const safe = sanitizeWorktreeName(raw) ?? throwOnEmpty;  // pass safe to resolveWorktreeMakeName","typeGuard":"function isValidWorktreeName(name: string): boolean {\n  return /^[A-Za-z0-9._-]+$/.test(name.trim());\n}","tryCatchPattern":null,"preventionTips":["Derive worktree names from slugs (branch, ticket id) rather than free-form titles.","Replace disallowed characters with dashes before validation.","Avoid slashes — worktree names are single branch/path segments."],"tags":["validation","worktree","naming"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}