paperclipai/paperclip · error

Retry was skipped.

Error message

Retry was skipped.

What it means

Same wakeup-response guard as the AgentDetail retry path, applied in IssueDetail: agentsApi.wakeup with reason "retry_failed_run" must return an object containing "id" (the new run). A response without id means the server skipped the retry, so this error is thrown, preferring the server's message. It exposes a soft server-side skip to the mutation's error state.

Source

Thrown at ui/src/pages/IssueDetail.tsx:1522

  });
  const resolvedActivity = activity ?? [];
  const resolvedLinkedRuns = linkedRuns ?? [];
  const retryFailedRun = useMutation({
    mutationFn: async (runId: string) => {
      const failedRun = resolvedLinkedRuns.find((run) => run.runId === runId);
      if (!failedRun) throw new Error("Failed run is no longer available.");
      const result = await agentsApi.wakeup(
        failedRun.agentId,
        {
          source: "on_demand",
          triggerDetail: "manual",
          reason: "retry_failed_run",
          payload: { issueId },
        },
        companyId,
      );
      if (!("id" in result)) {
        throw new Error(result.message ?? "Retry was skipped.");
      }
      return result;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({
        queryKey: queryKeys.issues.runs(issueId),
      });
      queryClient.invalidateQueries({
        queryKey: queryKeys.issues.liveRuns(issueId),
      });
      queryClient.invalidateQueries({
        queryKey: queryKeys.issues.activeRun(issueId),
      });
    },
    onError: (error) => {
      pushToast({
        title: "Run retry failed",
        body: error instanceof Error ? error.message : "Unable to retry run",

View on GitHub (pinned to 01ad858492)

Solutions

  1. Check result.message for the skip reason (pause/budget/concurrency) and resolve it.
  2. Refresh issue runs and the agent's status, then Retry again.
  3. Unpause the agent or clear budget/concurrency gates before retrying.
  4. Check server logs for the wakeup skip branch to confirm the exact guard hit.

Example fix

// before
if (!("id" in result)) {
  throw new Error(result.message ?? "Retry was skipped.");
}
// after
if (!("id" in result)) {
  toast.error(result.message ?? "Retry was skipped.");
  return null;
}
Defensive patterns

Strategy: type-guard

Validate before calling

// check agent gates before offering Retry
const canRetry = !agent.paused && !agent.budgetExceeded;

Type guard

const isNewRun = (r: unknown): r is { id: string } =>
  typeof r === "object" && r !== null && "id" in r && typeof (r as { id: unknown }).id === "string";

Try / catch

try {
  await retryFailedRun.mutateAsync(runId);
} catch (e) {
  toast.error(e.message);
  await queryClient.invalidateQueries({ queryKey: queryKeys.issues.runs(issueId) });
}

Prevention

When it happens

Trigger: agentsApi.wakeup(agentId, { reason: "retry_failed_run", payload: { issueId } }, companyId) resolves with a payload lacking "id" — the backend declined to create a retry run and returned only a message or non-run shape.

Common situations: The agent is paused, over budget, or at concurrency limits so on_demand wakeups are rejected; the failed run changed state concurrently; backend validation rejects the issue-linked retry payload.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/dc7be33a48225bf8. Report an issue: GitHub.