paperclipai/paperclip · error · Error
Invalid --by mode '${opts.by}'. Expected one of: auto, id, p
Error message
Invalid --by mode '${opts.by}'. Expected one of: auto, id, prefix. What it means
Thrown at the start of the `company delete <selector>` action when `opts.by` (defaulted to "auto", trimmed+lowercased) is not one of auto/id/prefix. The --by flag controls how the selector is interpreted: auto (detect), id (UUID lookup), or prefix (issue prefix match).
Source
Thrown at cli/src/commands/client/company.ts:1933
company
.command("delete")
.description("Delete a company by ID or shortname/prefix (destructive)")
.argument("<selector>", "Company ID or issue prefix (for example PAP)")
.option(
"--by <mode>",
"Selector mode: auto | id | prefix",
"auto",
)
.option("--yes", "Required safety flag to confirm destructive action", false)
.option(
"--confirm <value>",
"Required safety value: target company ID or shortname/prefix",
)
.action(async (selector: string, opts: CompanyDeleteOptions) => {
try {
const by = (opts.by ?? "auto").trim().toLowerCase() as CompanyDeleteSelectorMode;
if (!["auto", "id", "prefix"].includes(by)) {
throw new Error(`Invalid --by mode '${opts.by}'. Expected one of: auto, id, prefix.`);
}
const ctx = resolveCommandContext(opts);
const normalizedSelector = normalizeSelector(selector);
assertDeleteFlags(opts);
let target: Company | null = null;
const shouldTryIdLookup = by === "id" || (by === "auto" && isUuidLike(normalizedSelector));
if (shouldTryIdLookup) {
const byId = await ctx.api.get<Company>(apiPath`/api/companies/${normalizedSelector}`, { ignoreNotFound: true });
if (byId) {
target = byId;
} else if (by === "id") {
throw new Error(`No company found by ID '${normalizedSelector}'.`);
}
}
if (!target && ctx.companyId) {View on GitHub (pinned to 67001ec6eb)
Solutions
- Use `--by auto`, `--by id`, or `--by prefix`.
- Omit --by entirely to default to 'auto', which tries ID-then-prefix resolution.
- Run `paperclipai company delete --help` to confirm accepted values.
Example fix
# before paperclipai company delete acme --by name --yes --confirm ACME # after paperclipai company delete acme --by prefix --yes --confirm ACME
Defensive patterns
Strategy: validation
Validate before calling
const BY_MODES = ["auto", "id", "prefix"] as const;
type ByMode = typeof BY_MODES[number];
function normalizeByMode(v: string | undefined): ByMode {
const lower = (v ?? "auto").trim().toLowerCase();
if (!BY_MODES.includes(lower as ByMode)) {
throw new Error(`--by must be one of ${BY_MODES.join(", ")}`);
}
return lower as ByMode;
} Type guard
function isByMode(v: unknown): v is "auto" | "id" | "prefix" {
return typeof v === "string" && ["auto", "id", "prefix"].includes(v.toLowerCase());
} Prevention
- Default to omitting --by (auto) unless you need to force a resolution mode.
- Share the allow-list across wrappers and docs.
- Add a regression test for unknown --by values in CLI smoke tests.
When it happens
Trigger: Passing `--by name`, `--by uuid`, `--by shortname`, or any token outside the three allowed; a typo like `--by pref`.
Common situations: Developer guesses 'name' or 'uuid' as the by-mode; copying a flag value from documentation that used different terms.
Related errors
- Company selector is required.
- No company found by ID '${selector}'.
- No company found by shortname/prefix '${selector}'.
- Selector '${selector}' is ambiguous (matches both an ID and
- No company found for selector '${selector}'. Use company ID
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/d4d161f16ad61768.
Report an issue: GitHub.