paperclipai/paperclip · error

Principal is not a member of this company

Error message

Principal is not a member of this company

What it means

The principal targeted by a permission grant operation has no active membership in the company. Grants can only be managed for principals that belong to the company being modified.

Solutions

  1. Add the principal (agent or user) as a member of the company first, or use a principal that is already a member.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/src/services/plugin-host-services.ts:3046 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/a6b28a9ef0c92c08. Report an issue: GitHub.

Appendix: source

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

        ].filter((condition): condition is NonNullable<typeof condition> => Boolean(condition));
        const rows = await db
          .select()
          .from(principalPermissionGrants)
          .where(and(...conditions))
          .orderBy(principalPermissionGrants.principalType, principalPermissionGrants.principalId, principalPermissionGrants.permissionKey);
        return rows.map(redactGrant);
      },
      async setGrants(params) {
        const companyId = ensureCompanyId(params.companyId);
        await ensurePluginAvailableForCompany(companyId);
        if (params.principalType !== "agent" && params.principalType !== "user") {
          throw new Error("principalType must be 'agent' or 'user'");
        }
        if (params.principalType === "agent") {
          requireInCompany("Agent", await agents.getById(params.principalId), companyId);
        } else {
          const membership = await access.getMembership(companyId, params.principalType as PrincipalType, params.principalId);
          if (!membership) throw new Error("Principal is not a member of this company");
        }
        await access.setPrincipalGrants(
          companyId,
          params.principalType as PrincipalType,
          params.principalId,
          params.grants.map((grant) => ({
            permissionKey: grant.permissionKey as PermissionKey,
            scope: grant.scope ? sanitizeRecord(grant.scope) : null,
          })),
          params.grantedByUserId ?? null,
        );
        await logPluginActivity({
          companyId,
          action: "authorization.grants_updated_by_plugin",
          entityType: "principal_permission_grants",
          entityId: `${params.principalType}:${params.principalId}`,
          details: { grantCount: params.grants.length },
        });

View on GitHub (pinned to a7e689b3c3)