{"record":{"id":"bd287e603dcd631a","repo":"paperclipai/paperclip","slug":"worktree-selector-cannot-be-empty","errorCode":null,"errorMessage":"Worktree selector cannot be empty.","messagePattern":"Worktree selector cannot be empty\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/worktree.ts","lineNumber":2827,"sourceCode":"  if (choice.isCurrent) {\n    return resolveCurrentWorktreeEndpoint();\n  }\n  return {\n    rootPath: choice.worktree,\n    configPath: path.resolve(choice.worktree, \".paperclip\", \"config.json\"),\n    label: choice.branchLabel,\n    isCurrent: false,\n  };\n}\n\nfunction resolveWorktreeEndpointFromSelector(\n  selector: string,\n  opts?: { allowCurrent?: boolean },\n): ResolvedWorktreeEndpoint {\n  const trimmed = selector.trim();\n  const allowCurrent = opts?.allowCurrent !== false;\n  if (trimmed.length === 0) {\n    throw new Error(\"Worktree selector cannot be empty.\");\n  }\n\n  const currentEndpoint = resolveCurrentWorktreeEndpoint();\n  if (allowCurrent && trimmed === \"current\") {\n    return currentEndpoint;\n  }\n\n  const choices = toMergeSourceChoices(process.cwd());\n  const directPath = path.resolve(trimmed);\n  if (existsSync(directPath)) {\n    if (allowCurrent && directPath === currentEndpoint.rootPath) {\n      return currentEndpoint;\n    }\n    const configPath = path.resolve(directPath, \".paperclip\", \"config.json\");\n    if (!existsSync(configPath)) {\n      throw new Error(`Resolved worktree path ${directPath} does not contain .paperclip/config.json.`);\n    }\n    return {","sourceCodeStart":2809,"sourceCodeEnd":2845,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/worktree.ts#L2809-L2845","documentation":"Thrown by resolveWorktreeEndpointFromSelector after trimming the selector and finding it empty (length 0). The selector identifies a worktree endpoint for merge/seed operations (a path, a listed worktree dir name, a branch name, or 'current'). An empty/whitespace-only selector cannot resolve to anything and is rejected before any filesystem or git lookup.","triggerScenarios":"Passing an empty string as the worktree selector argument; a wrapper script passes an unset env var (empty); shell quoting produced an empty token.","commonSituations":"Programmatic caller forgot to set the selector variable; `paperclipai worktree:<cmd> \"\"`; selector sourced from a missing env var.","solutions":["Provide a non-empty selector: an absolute/relative path, a worktree directory name, a branch name, or the literal 'current'.","If driving the CLI programmatically, validate the selector is non-empty before invoking.","Use 'current' to target the worktree you're inside."],"exampleFix":"// before\npaperclipai worktree:merge-history --source \"\"\n// after\npaperclipai worktree:merge-history --source current","handlingStrategy":"validation","validationCode":"const trimmed = selector.trim();\nif (trimmed.length === 0) throw new Error(\"Selector required: path, name, branch, or 'current'\");","typeGuard":"function isNonEmptySelector(v: unknown): v is string {\n  return typeof v === \"string\" && v.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Validate selector is a non-empty string before calling the CLI programmatically.","Default to 'current' when no explicit selector is provided."],"tags":["worktree","validation","cli"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}