{"record":{"id":"2f5403580401e6ed","repo":"paperclipai/paperclip","slug":"actoruserid-userid-is-not-an-active-human-mem","errorCode":null,"errorMessage":"actorUserId \"${userId}\" is not an active human member of this company","messagePattern":"actorUserId \"(.+?)\" is not an active human member of this company","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/src/services/plugin-host-services.ts","lineNumber":905,"sourceCode":"   * `{ allowViewer: true }`; the default is failure-closed.\n   */\n  const requireActiveHumanMember = async (\n    companyId: string,\n    userId: string,\n    { allowViewer = false }: { allowViewer?: boolean } = {},\n  ): Promise<void> => {\n    const [membership] = await db\n      .select({ id: companyMemberships.id, membershipRole: companyMemberships.membershipRole })\n      .from(companyMemberships)\n      .where(and(\n        eq(companyMemberships.companyId, companyId),\n        eq(companyMemberships.principalType, \"user\"),\n        eq(companyMemberships.principalId, userId),\n        eq(companyMemberships.status, \"active\"),\n      ))\n      .limit(1);\n    if (!membership) {\n      throw new Error(`actorUserId \"${userId}\" is not an active human member of this company`);\n    }\n    if (!allowViewer && membership.membershipRole === \"viewer\") {\n      throw new Error(`actorUserId \"${userId}\" has viewer (read-only) access and cannot take this write action`);\n    }\n  };\n\n  /**\n   * Wake the assignee of a continuation issue after a plugin-relayed board-user\n   * interaction resolution, mirroring the web app's board interaction routes\n   * (routes/issues.ts's queueResolvedInteractionContinuationWakeup) so a\n   * confirmation accepted/rejected from chat resumes the agent the same way it\n   * would from the web app. Deliberately narrower than the HTTP helper: it\n   * carries the core interaction context plus the plan-review continuation\n   * payload (the confirmation kind the gateway resolves), and skips the\n   * checkbox/tool-action/item-verdict extras that the gateway's yes/no decision\n   * cards never produce. Failure-tolerant: a wake failure is logged, never\n   * thrown back to the plugin (the decision itself already applied).\n   */","sourceCodeStart":887,"sourceCodeEnd":923,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/server/src/services/plugin-host-services.ts#L887-L923","documentation":"requireActiveHumanMember found no active user membership for the given actorUserId in the company. Plugin write actions must be attributed to an active human member; the actor is missing, suspended, or not a member at all (failure-closed default).","triggerScenarios":"Thrown at server/src/services/plugin-host-services.ts:896 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Pass an actorUserId that is an active human member of the company, or omit it when the plugin is acting on its own behalf. Verify membership via the company members list before calling."],"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-14T00:17:10.932Z"}