paperclipai/paperclip · error · ToolGatewayHttpError
action_issue_closed
action_issue_closed
Error message
The issue for this tool action is closed; the approval has expired
What it means
Post-claim recheck in approved-action execution: the issue tied to the invocation is done or cancelled (or missing), so the claimed approval is expired and marked as such. This closes the race where a claim committed just before terminal-issue expiry revocation, ensuring governed side effects never run for closed issues.
Solutions
- The issue was closed, expiring the approval. Reopen/use another issue and request a new approval.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at server/src/services/tool-gateway.ts:4137 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/a55b50e59067d86f.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/tool-gateway.ts:7546
and(
eq(issues.id, invocation.issueId!),
eq(issues.companyId, invocation.companyId),
),
)
.limit(1);
if (issue && issue.status !== "done" && issue.status !== "cancelled") {
return { projectId: issue.projectId };
}
const expiredAt = new Date();
await db
.update(toolActionRequests)
.set({ status: "expired", resolvedAt: expiredAt, updatedAt: expiredAt })
.where(eq(toolActionRequests.id, claimed.id));
await reflectToolActionInteractionLifecycle({
actionRequestId: claimed.id,
status: "expired",
});
throw new ToolGatewayHttpError(
409,
"The issue for this tool action is closed; the approval has expired",
"action_issue_closed",
{ actionRequestId: claimed.id, invocationId: invocation.id },
);
}
async function restoreApprovedActionIdentity(
session: ToolGatewaySession,
identityContextId: string | undefined,
) {
if (!identityContextId) return;
const [origin] = await db
.select()
.from(runIdentityContexts)
.where(
and(
eq(runIdentityContexts.id, identityContextId),View on GitHub (pinned to 3f1d897a7c)