{"record":{"id":"05f4139f2050b518","repo":"paperclipai/paperclip","slug":"only-ceo-can-manage-permissions","errorCode":null,"errorMessage":"Only CEO can manage permissions","messagePattern":"Only CEO can manage permissions","errorType":"http","errorClass":null,"httpStatus":403,"severity":"error","filePath":"server/src/routes/agents.ts","lineNumber":3930,"sourceCode":"    const revisions = await svc.listConfigRevisions(id);\n    res.json(revisions.map((revision) => redactConfigRevision(revision)));\n  });\n\n  router.get(\"/agents/:id/config-revisions/:revisionId\", async (req, res) => {\n    const id = req.params.id as string;\n    const revisionId = req.params.revisionId as string;\n    const agent = await svc.getById(id);\n    if (!agent) {\n      res.status(404).json({ error: \"Agent not found\" });\n      return;\n    }\n    await assertCanReadConfigurations(req, agent.companyId);\n    const revision = await svc.getConfigRevision(id, revisionId);\n    if (!revision) {\n      res.status(404).json({ error: \"Revision not found\" });\n      return;\n    }\n    res.json(redactConfigRevision(revision));\n  });\n\n  router.post(\"/agents/:id/config-revisions/:revisionId/rollback\", async (req, res) => {\n    const id = req.params.id as string;\n    const revisionId = req.params.revisionId as string;\n    const existing = await getAccessibleResource(req, res, svc.getById(id), \"Agent not found\");\n    if (!existing) return;\n    await assertCanUpdateAgent(req, existing);\n\n    const revision = await svc.getConfigRevision(id, revisionId);\n    if (!revision) {\n      res.status(404).json({ error: \"Revision not found\" });\n      return;\n    }\n    const rollbackConfig = asRecord(revision.afterConfig);\n    if (!rollbackConfig) {\n      throw unprocessable(\"Invalid revision snapshot\");\n    }","sourceCodeStart":3912,"sourceCodeEnd":3948,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/routes/agents.ts#L3912-L3948","documentation":"PATCH /agents/:id/permissions requires CEO role; the actor (after checks) is not the company CEO. Permission management is restricted to the CEO principal, so the route refuses with this message.","triggerScenarios":"Thrown at server/src/routes/agents.ts:3473 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Perform permission changes as the CEO agent, or ask the CEO to make the change."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}