{"record":{"id":"af61523bcd0a7611","repo":"paperclipai/paperclip","slug":"only-board-users-can-vote-on-ai-feedback","errorCode":null,"errorMessage":"Only board users can vote on AI feedback","messagePattern":"Only board users can vote on AI feedback","errorType":"http","errorClass":null,"httpStatus":403,"severity":"error","filePath":"server/src/routes/issues.ts","lineNumber":13540,"sourceCode":"        agentId: actor.agentId,\n        userId: actor.actorType === \"user\" ? actor.actorId : null,\n        runId: actor.runId,\n      },\n      {\n        afterTombstone: async (deletedComment, tx) => {\n          await issueReferencesSvc.syncComment(deletedComment.id, tx);\n          await externalObjectsSvc.syncCommentSafely(deletedComment.id, tx);\n          annotationCleanup = await documentAnnotationsSvc.cleanupForIssueCommentDeletion(issue.id, deletedComment.id, {\n            actorType: actor.actorType,\n            actorId: actor.actorId,\n            agentId: actor.agentId,\n            userId: actor.actorType === \"user\" ? actor.actorId : null,\n            runId: actor.runId,\n          }, tx);\n          await Promise.all(\n            annotationCleanup.deletedCommentIds.map((annotationCommentId) =>\n              Promise.all([\n                issueReferencesSvc.deleteCommentSource(annotationCommentId, tx),\n                externalObjectsSvc.syncCommentSafely(annotationCommentId, tx),\n              ])\n            ),\n          );\n          await decisionTrainingSvc.scrubDeletedComments({\n            companyId: issue.companyId,\n            issueId: issue.id,\n            commentIds: [deletedComment.id, ...annotationCleanup.deletedCommentIds],\n            deletedAt: deletedComment.deletedAt ?? new Date(),\n          }, tx);\n        },\n      },\n    );\n    if (!deleted) {\n      res.status(404).json({ error: \"Comment not found\" });\n      return;\n    }\n","sourceCodeStart":13522,"sourceCodeEnd":13558,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/routes/issues.ts#L13522-L13558","documentation":"403 guard on POST /issues/:id/feedback-votes. Fires when the actor is not a board user; voting on AI feedback (up/down votes) is a board-user-only action, agent keys are rejected.","triggerScenarios":"Thrown at server/src/routes/issues.ts:12521 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":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}