{"record":{"id":"0d2cd08522f55edb","repo":"paperclipai/paperclip","slug":"pass-exactly-one-of-firstname-or-secondname","errorCode":null,"errorMessage":"Pass exactly one of ${firstName} or ${secondName}.","messagePattern":"Pass exactly one of (.+?) or (.+?)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/src/commands/pipelines.ts","lineNumber":730,"sourceCode":"  const parsed = Number(value);\n  if (!Number.isInteger(parsed) || parsed <= 0) throw new Error(`Invalid ${label}: ${value}`);\n  return parsed;\n}\n\nfunction parseCsv(value: string): string[] {\n  return value.split(\",\").map((item) => item.trim()).filter(Boolean);\n}\n\nfunction setIfDefined(target: JsonObject, key: string, value: unknown): void {\n  if (value !== undefined) target[key] = value;\n}\n\nfunction looksLikeUuid(value: string): boolean {\n  return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);\n}\n\nfunction exactlyOneFlag(first: boolean | undefined, second: boolean | undefined, firstName: string, secondName: string): string {\n  if (Boolean(first) === Boolean(second)) throw new Error(`Pass exactly one of ${firstName} or ${secondName}.`);\n  return first ? firstName : secondName;\n}\n\nfunction reviewDecisionFromOptions(opts: ReviewOptions): \"approve\" | \"reject\" | \"request_changes\" {\n  const selected = [\n    opts.approve ? { flag: \"--approve\", decision: \"approve\" as const } : null,\n    opts.reject ? { flag: \"--reject\", decision: \"reject\" as const } : null,\n    opts.requestChanges ? { flag: \"--request-changes\", decision: \"request_changes\" as const } : null,\n  ].filter((item): item is NonNullable<typeof item> => item !== null);\n  if (selected.length !== 1) {\n    throw new Error(\"Pass exactly one of --approve, --reject, or --request-changes.\");\n  }\n  return selected[0]!.decision;\n}\n\nfunction printPipeline(row: PipelineDetail | PipelineSummary | null, ctx: ResolvedClientContext): void {\n  if (!row) return printOutput(null, { json: ctx.json });\n  if (ctx.json) return printOutput(row, { json: true });","sourceCodeStart":712,"sourceCodeEnd":748,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/pipelines.ts#L712-L748","documentation":"Thrown by exactlyOneFlag() when two mutually-exclusive boolean flags are both set or both unset. It enforces exclusive choice semantics in the pipelines CLI (e.g. --accept vs --dismiss). The check coerces both values with Boolean() and errors when they compare equal, so passing neither is just as wrong as passing both.","triggerScenarios":"Running a pipelines command that calls exactlyOneFlag (line 566: accept/dismiss) with both `--accept --dismiss`, or with neither flag. The producer is `exactlyOneFlag(opts.accept, opts.dismiss, \"--accept\", \"--dismiss\")`.","commonSituations":"Operators confused about which acknowledgement flag to use, or shell scripts that conditionally add both flags. Also occurs when a default-true flag in a wrapper combines with an explicit override.","solutions":["Pass exactly one of the two named flags, removing the other.","If you genuinely want neither, you are likely calling the wrong subcommand — check the command's help (`--help`).","Audit wrapper scripts that build flag lists conditionally to ensure mutual exclusion."],"exampleFix":"// before\npaperclipai pipelines transition <id> --accept --dismiss\n// after\npaperclipai pipelines transition <id> --accept","handlingStrategy":"validation","validationCode":"function pickOne<T extends string>(flags: Array<[unknown, T]>, names: [T, T]): T {\n  const set = flags.filter(([, v]) => Boolean(v));\n  if (set.length !== 1) throw new Error(`Pass exactly one of ${names[0]} or ${names[1]}.`);\n  return set[0][1];\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In wrapper scripts, derive exclusive flags from a single decision variable rather than independent booleans.","Document the mutual exclusion in the command's --help text."],"tags":["cli","validation","flags","mutual-exclusion","pipelines"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}