paperclipai/paperclip · error · ToolGatewayHttpError

action_expired

action_expired

Error message

Tool review has expired

What it means

Expiry sweep during approved-action replay: actionRequest.expiresAt has passed, so the request is transitioned to expired with resolvedAt stamped before the 403/409 is returned. The approval is no longer valid; the agent must request a fresh approval if the action is still needed.

Solutions

  1. The approval expired. Request a fresh approval and execute within its validity window.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/src/services/tool-gateway.ts:5591 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/527249fa9c08df95. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/tool-gateway.ts:9413

          signedPayload.executionOnApprove === true
        ) {
          try {
            await executeApprovedAgentInvocation({ actionRequest, invocation });
          } catch {
            // The execution outcome is persisted on the invocation/request and
            // reflected onto the accepted interaction for the continuation wake.
          }
          const [settled] = await db
            .select()
            .from(toolActionRequests)
            .where(eq(toolActionRequests.id, actionRequest.id))
            .limit(1);
          return actionRequestResolution(settled ?? actionRequest);
        }
        return actionRequest;
      }
      if (actionRequest.expiresAt && actionRequest.expiresAt <= new Date())
        throw new ToolGatewayHttpError(
          409,
          "Tool review has expired",
          "action_expired",
        );
      if (
        !isTestOriginInvocation(invocation) &&
        signedPayload.executionOnApprove === true
      ) {
        const [issue] = await db
          .select()
          .from(issues)
          .where(
            and(
              eq(issues.id, invocation.issueId!),
              eq(issues.companyId, input.companyId),
            ),
          )
          .limit(1);

View on GitHub (pinned to 3f1d897a7c)