paperclipai/paperclip · error · Error

This retry could not start. Open the task to review its…

Error message

This retry could not start. Open the task to review its current access and recovery state.

What it means

The UI retryFailedRun helper calls POST /agents retry with reason "retry_failed_run". The retry API returns either a direct run ({id}) or an action request; when the action request resolves with status "failed" or "cancelled", the client throws this message telling the user the retry never started and to open the task for recovery state.

Solutions

  1. Open the issue/task in the board and check the failed run's current access and recovery state as the message advises.
  2. Inspect the action request payload returned by the retry API for the failure/cancellation reason.
  3. Re-authenticate or restore the agent's connection access, then retry.
  4. Ensure no other run is active on the issue before retrying the failed run.

Example fix

// before
await agentsApi.retryFailedRun(agentId, { reason: "retry_failed_run", failedRunId });
// after
try {
  await agentsApi.retryFailedRun(agentId, { reason: "retry_failed_run", failedRunId });
} catch (e) {
  navigate(`/issues/${issueId}`); // review access/recovery state in the board
  throw e;
}
Defensive patterns

Strategy: type-guard

Validate before calling

const run = await getFailedRun(agentId, failedRunId);
if (run.status !== "failed" || !run.retryable) throw new Error("run is not retryable; review access state first");

Type guard

function isRetryStartFailure(result: unknown): result is { actionId: string; status: "failed" | "cancelled" } {
  return typeof result === "object" && result !== null && "actionId" in result
    && ((result as any).status === "failed" || (result as any).status === "cancelled");
}

Try / catch

try {
  return await agentsApi.retryFailedRun(agentId, { reason: "retry_failed_run", failedRunId });
} catch (e) {
  toast.error(e.message, { action: { label: "Open task", onClick: () => navigate(`/issues/${issueId}`) } });
  return null;
}

Prevention

When it happens

Trigger: POST {agentPath}/retry with {reason:"retry_failed_run", failedRunId} returns an actionId whose final status is "failed" or "cancelled" — the server refused or aborted the retry (e.g. agent lacks access, run not retryable, approval denied).

Common situations: Retrying a run whose agent connection/credential was revoked; retrying while another run is active on the issue; retrying after the recovery window closed; user lacks permission to re-dispatch the agent.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/a4742cdd436a7736. Report an issue: GitHub.

Appendix: source

Thrown at ui/src/api/agents.ts:265

    companyId?: string,
  ) => api.post<AgentWakeupResponse>(agentPath(id, companyId, "/wakeup"), data),
  retryFailedRun: async (
    id: string,
    failedRunId: string,
    companyId: string,
  ) => {
    const result = await api.post<
      AgentWakeupResponse | ChatFailedRunRetryResponse
    >(agentPath(id, companyId, "/wakeup"), {
      source: "on_demand",
      triggerDetail: "manual",
      reason: "retry_failed_run",
      failedRunId,
    });
    if ("id" in result) return { runId: result.id, issueId: null };
    if ("actionId" in result) {
      if (result.status === "failed" || result.status === "cancelled") {
        throw new Error(
          "This retry could not start. Open the task to review its current access and recovery state.",
        );
      }
      return { runId: result.runId, issueId: result.issueId };
    }
    throw new Error(result.message ?? "Retry was skipped.");
  },
  loginWithClaude: (id: string, companyId?: string) =>
    api.post<ClaudeLoginResult>(agentPath(id, companyId, "/claude-login"), {}),
  startAdapterAuthLogin: (
    companyId: string,
    type: string,
    data: { environmentId: string; ttlSeconds?: number; aiConnection?: import("@paperclipai/shared").AiConnectionLoginIntent },
  ) =>
    api.post<AdapterAuthSessionResponse>(
      `/companies/${encodeURIComponent(companyId)}/adapters/${encodeURIComponent(type)}/login-sessions`,
      data,
    ),

View on GitHub (pinned to 3f1d897a7c)