paperclipai/paperclip · error

Use /api/agents/:id/permissions for permission changes

Error message

Use /api/agents/:id/permissions for permission changes

What it means

Contract guard on PATCH /agents/:id: the request body contains a 'permissions' key, but permissions must be changed through the dedicated permission endpoint (with its own authorization rules), so the general update route rejects the body with 422.

Solutions

  1. Use the /api/agents/:id/permissions endpoint for permission changes instead of this route.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/src/routes/agents.ts:3754 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at server/src/routes/agents.ts:4014

        title: agentsTable.title,
        status: agentsTable.status,
        adapterType: agentsTable.adapterType,
        runtimeConfig: agentsTable.runtimeConfig,
        lastHeartbeatAt: agentsTable.lastHeartbeatAt,
        companyName: companies.name,
        companyIssuePrefix: companies.issuePrefix,
      })
      .from(agentsTable)
      .innerJoin(companies, eq(agentsTable.companyId, companies.id))
      .orderBy(companies.name, agentsTable.name);

    const items: InstanceSchedulerHeartbeatAgent[] = rows
      .map((row) => {
        const policy = parseSchedulerHeartbeatPolicy(row.runtimeConfig);
        const statusEligible =
          row.status !== "paused" &&
          row.status !== "terminated" &&
          row.status !== "pending_approval";

        return {
          id: row.id,
          companyId: row.companyId,
          companyName: row.companyName,
          companyIssuePrefix: row.companyIssuePrefix,
          agentName: row.agentName,
          agentUrlKey: deriveAgentUrlKey(row.agentName, row.id),
          role: row.role as InstanceSchedulerHeartbeatAgent["role"],
          title: row.title,
          status: row.status as InstanceSchedulerHeartbeatAgent["status"],
          adapterType: row.adapterType,
          intervalSec: policy.intervalSec,
          heartbeatEnabled: policy.enabled,
          schedulerActive: statusEligible && policy.enabled && policy.intervalSec > 0,
          lastHeartbeatAt: row.lastHeartbeatAt,
        };
      })

View on GitHub (pinned to 3f1d897a7c)