{"record":{"id":"3968e6fcdef13320","repo":"paperclipai/paperclip","slug":"review-required","errorCode":"review_required","errorMessage":"Stage approval requires a human approver","messagePattern":"Stage approval requires a human approver","errorType":"http","errorClass":"HttpError","httpStatus":403,"severity":"error","filePath":"server/src/services/pipelines.ts","lineNumber":1067,"sourceCode":"\nfunction assertStageEnabled(stage: typeof pipelineStages.$inferSelect, action: string) {\n  const config = normalizeStageConfig(stage.kind, stageConfig(stage));\n  if (config.disabled !== true) return;\n  throw unprocessable(\"Pipeline stage is disabled\", {\n    code: \"stage_disabled\",\n    action,\n    stageId: stage.id,\n    stageKey: stage.key,\n  });\n}\n\nfunction assertActorCanApproveStageExit(stage: typeof pipelineStages.$inferSelect, actor: PipelineActor) {\n  const config = normalizeStageConfig(stage.kind, stageConfig(stage));\n  if (config.requireApproval !== true) return;\n  const approver = config.approver ?? { kind: \"any_human\" };\n  if (approver.kind === \"any_human\") {\n    if (actor.type === \"user\") return;\n    throw new HttpError(403, \"Stage approval requires a human approver\", { code: \"review_required\" });\n  }\n  if (approver.kind === \"user\") {\n    if (actor.type === \"user\" && actor.userId === approver.id) return;\n    throw new HttpError(403, \"Stage approval requires the configured user approver\", {\n      code: \"review_required\",\n      approver,\n    });\n  }\n  if (actor.type === \"agent\" && actor.agentId === approver.id) return;\n  throw new HttpError(403, \"Stage approval requires the configured agent approver\", {\n    code: \"review_required\",\n    approver,\n  });\n}\n\nfunction assertReviewTargetsInSet(\n  kind: PipelineStageKind | string,\n  config: PipelineStageConfig,","sourceCodeStart":1049,"sourceCodeEnd":1085,"githubUrl":"https://github.com/paperclipai/paperclip/blob/120ae5428fa29bee300bcf806491cd4d965fbb7c/server/src/services/pipelines.ts#L1049-L1085","documentation":"Governance guard in assertActorCanApproveStageExit: the stage's config requires approval (requireApproval=true) but the resolved approver is not a human actor. Automation/agent actors cannot satisfy a human-approval gate, so the stage-exit approval is rejected.","triggerScenarios":"Thrown at server/src/services/pipelines.ts:1067 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Approve the stage as a human user; agent actors cannot approve this stage."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"120ae5428fa29bee300bcf806491cd4d965fbb7c","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}