paperclipai/paperclip · error
actorUserId is required to decide an approval on behalf of a
Error message
actorUserId is required to decide an approval on behalf of a board user
What it means
approvals.decide() was called without actorUserId. Approval decisions are board-user actions; the host requires the acting human user to re-verify their membership and record attribution.
Source
Thrown at server/src/services/plugin-host-services.ts:2668
async get(params) {
const companyId = ensureCompanyId(params.companyId);
await ensurePluginAvailableForCompany(companyId);
const approval = await approvalSvc.getById(params.approvalId);
if (!approval || approval.companyId !== companyId) return null;
return redactApprovalPayload(approval) as any;
},
async decide(params) {
const companyId = ensureCompanyId(params.companyId);
await ensurePluginAvailableForCompany(companyId);
const existing = await approvalSvc.getById(params.approvalId);
if (!existing || existing.companyId !== companyId) {
throw new Error(`Approval "${params.approvalId}" not found`);
}
// Deciding an approval is a board-user action (the web app's approval
// decision routes are board-only). Re-verify active membership at apply
// time; never trust the plugin-supplied identity.
if (!params.actorUserId) {
throw new Error("actorUserId is required to decide an approval on behalf of a board user");
}
await requireActiveHumanMember(companyId, params.actorUserId);
const { approval, applied } = params.action === "approve"
? await approvalSvc.approve(params.approvalId, params.actorUserId, params.decisionNote ?? null)
: await approvalSvc.reject(params.approvalId, params.actorUserId, params.decisionNote ?? null);
await logPluginActivity({
companyId,
action: params.action === "approve" ? "approval.approved" : "approval.rejected",
entityType: "approval",
entityId: approval.id,
actor: { actorUserId: params.actorUserId },
details: {
type: approval.type,
requestedByAgentId: approval.requestedByAgentId,
applied,
},View on GitHub (pinned to a7e689b3c3)
Solutions
- Provide actorUserId when deciding an approval on behalf of a board user; approvals cannot be decided anonymously by a plugin.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at server/src/services/plugin-host-services.ts:2659 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/b7671fff0bed2863.
Report an issue: GitHub.