{"record":{"id":"87e623bea2cc52a3","repo":"paperclipai/paperclip","slug":"only-the-example-author-can-change-decision-traini","errorCode":null,"errorMessage":"Only the example author can change decision training examples","messagePattern":"Only the example author can change decision training examples","errorType":"http","errorClass":null,"httpStatus":403,"severity":"error","filePath":"server/src/routes/decision-training.ts","lineNumber":46,"sourceCode":"  if (!req.actor.userId) {\n    res.status(403).json({ error: \"Board user context required\" });\n    return null;\n  }\n  return req.actor.userId;\n}\n\nfunction parseExampleId(req: Request, res: Response) {\n  const parsed = exampleIdSchema.safeParse(req.params.id);\n  if (!parsed.success) {\n    res.status(404).json({ error: \"Decision training example not found\" });\n    return null;\n  }\n  return parsed.data;\n}\n\nfunction requireExampleOwner(res: Response, userId: string, createdByUserId: string) {\n  if (userId !== createdByUserId) {\n    res.status(403).json({ error: \"Only the example author can change decision training examples\" });\n    return false;\n  }\n  return true;\n}\n\nexport function decisionTrainingRoutes(db: Db) {\n  const router = Router();\n  const svc = decisionTrainingService(db);\n\n  router.post(\n    \"/companies/:companyId/decision-training\",\n    validate(createSchema),\n    async (req, res) => {\n      const companyId = req.params.companyId as string;\n      assertCompanyAccess(req, companyId);\n      const userId = requireHumanUser(req, res);\n      if (!userId) return;\n","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/server/src/routes/decision-training.ts#L28-L64","documentation":"Ownership gate in requireExampleOwner: the authenticated board user is not the user who created this decision-training example, and only the author may edit or delete examples, so the mutation is refused with 403.","triggerScenarios":"Thrown at server/src/routes/decision-training.ts:46 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["This is an authorization rule, not a bug: perform the action with an actor that satisfies the stated constraint (board user, the owning agent, or an in-scope resource).","If access should be allowed, verify the actor's credentials/company scope and the resource's ownership before retrying."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"a7e689b3c35347b529cb9f54c9b9a8575a3dcab6","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}