paperclipai/paperclip · error · Error
paperclip_runner_attachment_staging_not_authorized
paperclip_runner_attachment_staging_not_authorized
Error message
paperclip_runner_attachment_staging_not_authorized
What it means
Authorization gate for staging runner attachment bytes: the run must exist and its agentStatus must not be paused, terminated, pending_approval, or error. Staging is only permitted for actively running agents; a missing run row or a halted lifecycle state rejects the handoff so paused/failed runs cannot inject files.
Solutions
- Check the run's current agentStatus before staging and only stage while the run is active
- Resume/restart the run (resolve pause or approval) and then retry the attachment handoff
- Verify the runId/binding is correct — a missing run row also produces this error
Defensive patterns
Strategy: try-catch
Validate before calling
const run = await getRun(runId);
if (!run || ["paused","terminated","pending_approval","error"].includes(run.agentStatus)) {
throw new Error(`run ${runId} not stageable (status=${run?.agentStatus ?? "missing"})`);
} Type guard
const isStageableRun = (run) => !!run && !["paused","terminated","pending_approval","error"].includes(run.agentStatus);
Try / catch
try { await stageAttachmentForRun(input); } catch (e) { if (e.message === "paperclip_runner_attachment_staging_not_authorized") { /* stop streaming, wait for resume, or abort the handoff */ } else throw e; } Prevention
- Poll run status before and during attachment handoffs; stop staging on any halt state
- Handle budget hard-stops and approval gates by suspending file handoff, not forcing it
- Validate runId/binding correctness to avoid staging against an expired or wrong run
When it happens
Trigger: Calling the attachment staging entrypoint when the run row is absent (unknown/expired runId), or run.agentStatus is 'paused', 'terminated', 'pending_approval', or 'error'.
Common situations: Runner keeps streaming attachments after the task hit a budget hard-stop (paused); staging attempted during an approval gate (pending_approval); stale runner retries after the run errored or was terminated; wrong runId passed by the caller.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- access.reasonCode
- ACPX provider ownership admission is already active
- ACPX provider ownership admission is closed
- ACPX runtime host is closing
- action_task_closed
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/522d910be26af01d.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/native-runtime/native-runner-file-handoff.ts:859
eq(heartbeatRuns.agentId, input.binding.agentId),
eq(heartbeatRuns.nativeIssueId, input.binding.issueId),
eq(heartbeatRuns.runtimeMode, "native"),
inArray(heartbeatRuns.status, ["queued", "running"]),
eq(issues.id, input.binding.issueId),
eq(issues.companyId, input.binding.companyId),
eq(issues.executionRunId, input.binding.runId),
eq(agents.id, input.binding.agentId),
eq(agents.companyId, input.binding.companyId),
),
)
.limit(1);
if (
!run ||
["paused", "terminated", "pending_approval", "error"].includes(
run.agentStatus,
)
) {
throw new Error("paperclip_runner_attachment_staging_not_authorized");
}
const reviewContext = readNativeReviewAssignmentContext(run.contextSnapshot);
const nativeReview = reviewContext
? await getNativeReviewAssignment(input.db, {
companyId: input.binding.companyId,
issueId: input.binding.issueId,
agentId: input.binding.agentId,
contextSnapshot: reviewContext,
})
: null;
if (run.assigneeAgentId !== input.binding.agentId && !nativeReview) {
throw new Error("paperclip_runner_attachment_staging_not_authorized");
}
const selections = wakeAttachmentSelections(run.contextSnapshot);
if (selections.length > MAX_NATIVE_STAGED_ATTACHMENTS) {
throw new Error("paperclip_runner_attachment_staging_count_denied");
}
const workspaceRoot =View on GitHub (pinned to 3f1d897a7c)