paperclipai/paperclip · error · ToolGatewayHttpError

action_expired

action_expired

Error message

Tool action request approval 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.

Source

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

    // this read has raced an execution that was approved, claimed, and verified
    // while the issue was open; that instant is irreducible for an external
    // side effect gated by DB state (holding a DB lock across a remote provider
    // call is not an option), and the accepted linearization is that the
    // execution wins — its result still lands on the expired card via
    // reflectToolActionInteractionLifecycle.
    await assertIssueOpenForApprovedAction({ claimed, invocation });

    const startedAt = Date.now();
    await db
      .update(toolInvocations)
      .set({ status: "executing", approvalState: "approved", startedAt: new Date(), updatedAt: new Date() })
      .where(eq(toolInvocations.id, invocation.id));
    await reflectToolActionInteractionLifecycle({ actionRequestId: claimed.id, status: "executing" });

    try {
      const executionTimeoutMs = timeoutMs(APPROVED_EXECUTION_TIMEOUT_MS);
      const result = tool.providerType === "mcp_remote_http"
        ? (await executeRemoteHttpTool(session, tool, parameters, executionTimeoutMs, invocation.id)).result
        : tool.providerType === "mcp_local_stdio"
          ? (await executeLocalStdioTool(session, tool, parameters, executionTimeoutMs)).result
          : tool.providerType !== "paperclip_plugin"
            ? await runWithTimeout(executeBuiltinTool(session, tool, parameters), executionTimeoutMs)
            : (() => { throw new ToolGatewayHttpError(409, "Plugin actions cannot execute outside their originating run", "approved_execution_unsupported"); })();
      const resultRecord = asRecord(result);
      if (resultRecord?.error) throw new ToolGatewayHttpError(502, String(resultRecord.content || resultRecord.error), "tool_execution_failed");
      const resultValidation = validateToolContent({
        value: result,
        direction: "result",
        sensitiveMode: "redact",
        promptInjectionMode: "block",
      });
      const now = new Date();
      await db.update(toolInvocations).set({
        status: "succeeded",
        resultHash: resultValidation.summary.sha256 ?? null,
        resultSummary: resultValidation.summary,

View on GitHub (pinned to 01ad858492)

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@01ad858492 (2026-08-18). Data as JSON: /api/errors/527249fa9c08df95. Report an issue: GitHub.