paperclipai/paperclip · error
Status-only recovery runs cannot create or modify approvals
Error message
Status-only recovery runs cannot create or modify approvals
What it means
Permission guard assertApprovalMutationAllowedByRunContext: an agent actor whose run is a status-only recovery run (per its contextSnapshot) may not create or modify approvals, so the guard throws/returns an error response. It fires when a recovery run's agent attempts approval mutations — reserved for normal runs with full approval authority.
Source
Thrown at server/src/routes/approvals.ts:193
async function assertApprovalMutationAllowedByRunContext(req: Request, res: any, companyId: string) {
if (req.actor.type !== "agent") return true;
const runId = req.actor.runId?.trim();
if (!runId || !req.actor.agentId) return true;
const run = await db
.select({
id: heartbeatRuns.id,
companyId: heartbeatRuns.companyId,
agentId: heartbeatRuns.agentId,
contextSnapshot: heartbeatRuns.contextSnapshot,
})
.from(heartbeatRuns)
.where(eq(heartbeatRuns.id, runId))
.then((rows) => rows[0] ?? null);
if (!run || run.companyId !== companyId || run.agentId !== req.actor.agentId) return true;
if (!isStatusOnlyRecoveryContext(run.contextSnapshot)) return true;
res.status(403).json({
error: "Status-only recovery runs cannot create or modify approvals",
details: {
companyId,
runId: run.id,
recoveryIntent: "status_only",
resumeRequiresNormalModel: true,
},
});
return false;
}
router.get("/companies/:companyId/approvals", async (req, res) => {
const companyId = req.params.companyId as string;
assertCompanyAccess(req, companyId);
if (!(await assertApprovalAccessAllowed(req, res, companyId))) return;
const status = req.query.status as string | undefined;
const result = await svc.list(companyId, status);
res.json(result.map((approval) => redactApprovalPayload(approval)));View on GitHub (pinned to 5716fe907e)
Solutions
- Retry the approval mutation from a normal (non-recovery) run or from board/operator context.
- Downgrade the recovery run to status-only actions; request a human or a regular run to handle the approval.
- Verify req.actor.runId/contextSnapshot classification is correct if the run is not intended to be status-only.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at server/src/routes/approvals.ts:193 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of paperclipai/paperclip@5716fe907e (2026-09-02).
Data as JSON: /api/errors/f5e9374eecee768b.
Report an issue: GitHub.