{"record":{"id":"b5d2427ba135f43d","repo":"paperclipai/paperclip","slug":"approval-request-failed","errorCode":null,"errorMessage":"Approval request failed.","messagePattern":"Approval request failed\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/client/teams.ts","lineNumber":425,"sourceCode":"        `A Paperclip CLI agent-run attempted to install catalog team \"${trimmedRef}\" into company \"${ctx.companyId}\", ` +\n        `but the API denied the install with: ${error.message}.`,\n      recommendedAction:\n        \"Approve the catalog team source and rerun the install with a board or agent-creator token, or grant agents:create to the requesting agent and rerun the same command.\",\n      risks: [\n        \"Catalog team installation can create agents, projects, tasks, routines, skills, and secret bindings.\",\n        \"Only approve after checking the catalog source, selected files, target manager, and collision strategy.\",\n      ],\n      installAttempt: {\n        companyId: ctx.companyId,\n        catalogRef: trimmedRef,\n        options: approvalInstallOptions,\n        deniedReason: error.message,\n      },\n    },\n  };\n  const approval = await ctx.api.post<Approval>(apiPath`/api/companies/${ctx.companyId}/approvals`, payload);\n  if (!approval) {\n    throw new Error(\"Approval request failed.\");\n  }\n  return {\n    status: \"approval_requested\",\n    approval,\n    installAttempt: {\n      companyId: ctx.companyId,\n      catalogRef: trimmedRef,\n      options: returnedInstallOptions,\n      deniedReason: error.message,\n    },\n  };\n}\n\nfunction omitInstallSecretValues(options: CatalogTeamInstallOptions): CatalogTeamInstallOptions {\n  if (!options.secretValues) return options;\n  const { secretValues: _secretValues, ...safeOptions } = options;\n  return safeOptions;\n}","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/client/teams.ts#L407-L443","documentation":"Thrown by requestInstallApproval() when POST /api/companies/{id}/approvals returns null/undefined. This is the second stage of the 403-fallback flow: the install was denied, the CLI tried to create a board approval request instead, and the server returned no approval object. The CLI refuses to report success without an approval record.","triggerScenarios":"`teams install` denied with 403 (agents:create) → fallback approval POST returns empty 2xx body, 204, or the route is missing/disabled. Also possible if the approvals endpoint itself errors in a way that resolves to null.","commonSituations":"Version skew (CLI expects an Approval body, server returns 204/no-content), permissions issue on approval creation, or a proxy stripping the response body.","solutions":["Check CLI/server version alignment for the approvals contract.","Retry the install; if the 403 was transient, the fallback may not be needed.","Inspect the raw approval POST response (status + body) with curl to see what the server returns."],"exampleFix":"# diagnose the fallback contract\ncurl -sS -X POST \"$API/api/companies/$CID/approvals\" \\\n  -H \"authorization: Bearer $TOKEN\" -H \"content-type: application/json\" \\\n  -d '{\"type\":\"request_board_approval\",\"issueIds\":[],\"payload\":{\"title\":\"t\",\"summary\":\"s\",\"instructions\":[],\"installAttempt\":{\"companyId\":\"'$CID'\",\"catalogRef\":\"ref\",\"options\":{},\"deniedReason\":\"x\"}}}' \\\n  | jq .","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isApproval(v: unknown): v is Approval {\n  return v != null && typeof v === \"object\" && \"id\" in (v as object);\n}","tryCatchPattern":"try {\n  await run([\"teams\", \"install\", ref, \"--request-approval-on-forbidden\"]);\n} catch (err) {\n  if (err instanceof Error && /Approval request failed/.test(err.message)) {\n    console.error(\"Approval endpoint returned no body. Check server version / contract.\");\n    process.exit(2);\n  }\n  throw err;\n}","preventionTips":["Keep CLI and server versions aligned for the approvals contract.","Retry the install directly if the 403 may have been transient.","Inspect the raw approval POST to confirm the response shape."],"tags":["cli","api","teams","approval","null-response","install"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}