paperclipai/paperclip · error · Error

actorUserId "${userId}" is not an active human member of thi

Error message

actorUserId "${userId}" is not an active human member of this company

What it means

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).

Source

Thrown at server/src/services/plugin-host-services.ts:905

   * `{ allowViewer: true }`; the default is failure-closed.
   */
  const requireActiveHumanMember = async (
    companyId: string,
    userId: string,
    { allowViewer = false }: { allowViewer?: boolean } = {},
  ): Promise<void> => {
    const [membership] = await db
      .select({ id: companyMemberships.id, membershipRole: companyMemberships.membershipRole })
      .from(companyMemberships)
      .where(and(
        eq(companyMemberships.companyId, companyId),
        eq(companyMemberships.principalType, "user"),
        eq(companyMemberships.principalId, userId),
        eq(companyMemberships.status, "active"),
      ))
      .limit(1);
    if (!membership) {
      throw new Error(`actorUserId "${userId}" is not an active human member of this company`);
    }
    if (!allowViewer && membership.membershipRole === "viewer") {
      throw new Error(`actorUserId "${userId}" has viewer (read-only) access and cannot take this write action`);
    }
  };

  /**
   * Wake the assignee of a continuation issue after a plugin-relayed board-user
   * interaction resolution, mirroring the web app's board interaction routes
   * (routes/issues.ts's queueResolvedInteractionContinuationWakeup) so a
   * confirmation accepted/rejected from chat resumes the agent the same way it
   * would from the web app. Deliberately narrower than the HTTP helper: it
   * carries the core interaction context plus the plan-review continuation
   * payload (the confirmation kind the gateway resolves), and skips the
   * checkbox/tool-action/item-verdict extras that the gateway's yes/no decision
   * cards never produce. Failure-tolerant: a wake failure is logged, never
   * thrown back to the plugin (the decision itself already applied).
   */

View on GitHub (pinned to a7e689b3c3)

Solutions

  1. 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.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/src/services/plugin-host-services.ts:896 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-18). Data as JSON: /api/errors/2f5403580401e6ed. Report an issue: GitHub.