paperclipai/paperclip · error
Pass exactly one of ${firstName} or ${secondName}.
Error message
Pass exactly one of ${firstName} or ${secondName}. What it means
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.
Source
Thrown at cli/src/commands/pipelines.ts:730
const parsed = Number(value);
if (!Number.isInteger(parsed) || parsed <= 0) throw new Error(`Invalid ${label}: ${value}`);
return parsed;
}
function parseCsv(value: string): string[] {
return value.split(",").map((item) => item.trim()).filter(Boolean);
}
function setIfDefined(target: JsonObject, key: string, value: unknown): void {
if (value !== undefined) target[key] = value;
}
function looksLikeUuid(value: string): boolean {
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);
}
function exactlyOneFlag(first: boolean | undefined, second: boolean | undefined, firstName: string, secondName: string): string {
if (Boolean(first) === Boolean(second)) throw new Error(`Pass exactly one of ${firstName} or ${secondName}.`);
return first ? firstName : secondName;
}
function reviewDecisionFromOptions(opts: ReviewOptions): "approve" | "reject" | "request_changes" {
const selected = [
opts.approve ? { flag: "--approve", decision: "approve" as const } : null,
opts.reject ? { flag: "--reject", decision: "reject" as const } : null,
opts.requestChanges ? { flag: "--request-changes", decision: "request_changes" as const } : null,
].filter((item): item is NonNullable<typeof item> => item !== null);
if (selected.length !== 1) {
throw new Error("Pass exactly one of --approve, --reject, or --request-changes.");
}
return selected[0]!.decision;
}
function printPipeline(row: PipelineDetail | PipelineSummary | null, ctx: ResolvedClientContext): void {
if (!row) return printOutput(null, { json: ctx.json });
if (ctx.json) return printOutput(row, { json: true });View on GitHub (pinned to 67001ec6eb)
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.
Example fix
// before paperclipai pipelines transition <id> --accept --dismiss // after paperclipai pipelines transition <id> --accept
Defensive patterns
Strategy: validation
Validate before calling
function pickOne<T extends string>(flags: Array<[unknown, T]>, names: [T, T]): T {
const set = flags.filter(([, v]) => Boolean(v));
if (set.length !== 1) throw new Error(`Pass exactly one of ${names[0]} or ${names[1]}.`);
return set[0][1];
} Prevention
- 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.
When it happens
Trigger: 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")`.
Common situations: 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.
Related errors
- Pass exactly one of --approve, --reject, or --request-change
- Use only one of --value or --value-env.
- Use either a skill reference or --all, not both.
- Invalid ${label}: ${value}
- --payload must be a JSON object
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/0d2cd08522f55edb.
Report an issue: GitHub.