{"record":{"id":"6a10e00689d95ba1","repo":"paperclipai/paperclip","slug":"failed-to-create-api-key","errorCode":null,"errorMessage":"Failed to create API key","messagePattern":"Failed to create API key","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/client/agent.ts","lineNumber":791,"sourceCode":"        \"--no-install-skills\",\n        \"Skip installing Paperclip skills into ~/.codex/skills and ~/.claude/skills\",\n      )\n      .action(async (agentRef: string, opts: AgentLocalCliOptions) => {\n        try {\n          const ctx = resolveCommandContext(opts, { requireCompany: true });\n          const query = new URLSearchParams({ companyId: ctx.companyId ?? \"\" });\n          const agentRow = await ctx.api.get<Agent>(\n            `${apiPath`/api/agents/${agentRef}`}?${query.toString()}`,\n          );\n          if (!agentRow) {\n            throw new Error(`Agent not found: ${agentRef}`);\n          }\n\n          const now = new Date().toISOString().replaceAll(\":\", \"-\");\n          const keyName = opts.keyName?.trim() ? opts.keyName.trim() : `local-cli-${now}`;\n          const key = await ctx.api.post<CreatedAgentKey>(apiPath`/api/agents/${agentRow.id}/keys`, { name: keyName });\n          if (!key) {\n            throw new Error(\"Failed to create API key\");\n          }\n\n          const installSummaries: SkillsInstallSummary[] = [];\n          if (opts.installSkills !== false) {\n            const skillsDir = await resolvePaperclipSkillsDir(__moduleDir, [path.resolve(process.cwd(), \"skills\")]);\n            if (!skillsDir) {\n              throw new Error(\n                \"Could not locate local Paperclip skills directory. Expected ./skills in the repo checkout.\",\n              );\n            }\n\n            installSummaries.push(\n              await installSkillsForTarget(skillsDir, codexSkillsHome(), \"codex\"),\n              await installSkillsForTarget(skillsDir, claudeSkillsHome(), \"claude\"),\n            );\n          }\n\n          const exportsText = buildAgentEnvExports({","sourceCodeStart":773,"sourceCodeEnd":809,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/client/agent.ts#L773-L809","documentation":"Thrown by the local-cli action when POST /api/agents/{id}/keys returned a falsy value (the client typed the response as CreatedAgentKey but the server returned null/undefined/empty). The agent lookup already succeeded ([7] would have fired otherwise), so this is a key-creation endpoint returning an unexpected empty body.","triggerScenarios":"The agent exists but the key-creation route returned no body (e.g. 200 with empty JSON, or the client deserialized a 204/null). This typically indicates a server bug or a version mismatch where /keys changed shape, or the API client's response unwrapping returned undefined.","commonSituations":"Server version older/newer than the CLI expects for the /keys contract. A proxy stripping the response body. Rare server-side error swallowed into a 200 with null.","solutions":["Check CLI and server versions are aligned (npm view / release notes for /api/agents/:id/keys).","Retry — a transient empty response can occur during deploys.","Inspect the server logs for the /keys request to see what body it returned.","If persistent, report the server response shape as a bug; fall back to creating the key via the board UI."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isCreatedKey(v: unknown): v is { key: string; name: string; id?: string } {\n  return typeof v === 'object' && v !== null && typeof (v as any).key === 'string';\n}","tryCatchPattern":"let key;\ntry { key = await api.post(`/api/agents/${agent.id}/keys`, { name: keyName }); }\ncatch (err) { /* network/HTTP errors */ throw err; }\nif (!isCreatedKey(key)) {\n  console.error('Server returned no key body from /keys — possible version mismatch. Create the key in the board UI.');\n  process.exit(3);\n}","preventionTips":["Keep CLI and server versions in sync; the /keys contract changes between releases.","Retry once on empty responses during deploys.","Have a board-UI fallback for key creation when the API path misbehaves.","Log the server response shape when this fires so the mismatch is diagnosable."],"tags":["cli","agent","api-keys","server-mismatch"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}