{"record":{"id":"616f0431e54f5f2b","repo":"paperclipai/paperclip","slug":"agent-reference-is-required-616f04","errorCode":null,"errorMessage":"Agent reference is required","messagePattern":"Agent reference is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/client/token.ts","lineNumber":219,"sourceCode":"    board\n      .command(\"revoke\")\n      .description(\"Revoke a board API key\")\n      .argument(\"<keyId>\", \"Board API key ID\")\n      .action(async (keyId: string, opts: BaseClientOptions) => {\n        try {\n          const ctx = resolveCommandContext(opts);\n          const result = await ctx.api.delete<{ ok: true; keyId: string }>(apiPath`/api/board-api-keys/${keyId}`);\n          printOutput(result ?? { ok: true, keyId }, { json: ctx.json });\n        } catch (err) {\n          handleCommandError(err);\n        }\n      }),\n  );\n}\n\nasync function resolveAgent(api: { get<T>(path: string): Promise<T | null> }, companyId: string, agentRef: string): Promise<Agent> {\n  const trimmed = agentRef.trim();\n  if (!trimmed) throw new Error(\"Agent reference is required\");\n  if (/^[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(trimmed)) {\n    const agent = await api.get<Agent>(apiPath`/api/agents/${trimmed}`);\n    if (!agent || agent.companyId !== companyId) throw new Error(`Agent not found: ${agentRef}`);\n    return agent;\n  }\n  const query = new URLSearchParams({ companyId });\n  const agent = await api.get<Agent>(`${apiPath`/api/agents/${trimmed}`}?${query.toString()}`);\n  if (!agent || agent.companyId !== companyId) throw new Error(`Agent not found: ${agentRef}`);\n  return agent;\n}\n\nfunction resolveBoardKeyExpiresAt(opts: BoardTokenOptions): Date | null | undefined {\n  if (opts.neverExpires) return null;\n  if (opts.expiresAt?.trim()) {\n    const date = new Date(opts.expiresAt.trim());\n    if (!Number.isFinite(date.getTime())) throw new Error(`Invalid --expires-at value: ${opts.expiresAt}`);\n    return date;\n  }","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/client/token.ts#L201-L237","documentation":"Thrown by resolveAgent in token.ts when the agent reference argument trims to an empty string. It is a pre-flight guard before any lookup attempt; the --agent option is logically required but reached here as empty.","triggerScenarios":"Calling `token agent create` with `--agent \"\"`, `--agent \"   \"`, or omitting --agent in a code path that does not declare it requiredOption. resolveAgent trims and rejects empty before UUID/name resolution.","commonSituations":"A wrapper script passing an unset env var (`--agent \"$AGENT_ID\"` with AGENT_ID empty), or a command alias that dropped the argument.","solutions":["Provide a non-empty agent ID, shortname, or name: --agent <value>.","If scripting, guard the env var before invoking the CLI.","Use --agent with a UUID for the most direct resolution."],"exampleFix":"// before\n--agent \"\"\n// after\n--agent \"01f3c2d4-...\"  # or an agent shortname","handlingStrategy":"validation","validationCode":"const agentRef = (opts.agent ?? \"\").trim();\nif (!agentRef) {\n  console.error(\"--agent is required (ID, shortname, or name).\");\n  process.exit(1);\n}","typeGuard":"function isNonEmptyAgentRef(value: string | undefined): value is string {\n  return typeof value === \"string\" && value.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Always pass a non-empty --agent value.","In scripts, check the env var is set before forwarding it.","Prefer UUIDs for deterministic resolution."],"tags":["cli","argument-validation","agent-resolution"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}