paperclipai/paperclip · error

Retry was skipped.

Error message

Retry was skipped.

What it means

In the LegacyInbox retry flow, agentsApi.wakeup with reason "retry_failed_run" must return a new run object containing "id". If the response lacks an id, the server skipped the retry and returned only a message; this error is thrown with the server message as fallback. The mutation's onSuccess navigates to the new run, so a skipped retry cannot proceed.

Source

Thrown at ui/src/pages/LegacyInbox.tsx:1685

  const [retryingRunIds, setRetryingRunIds] = useState<Set<string>>(new Set());

  const retryRunMutation = useMutation({
    mutationFn: async (run: HeartbeatRun) => {
      const payload: Record<string, unknown> = {};
      const context = run.contextSnapshot as Record<string, unknown> | null;
      if (context) {
        if (typeof context.issueId === "string" && context.issueId) payload.issueId = context.issueId;
        if (typeof context.taskId === "string" && context.taskId) payload.taskId = context.taskId;
        if (typeof context.taskKey === "string" && context.taskKey) payload.taskKey = context.taskKey;
      }
      const result = await agentsApi.wakeup(run.agentId, {
        source: "on_demand",
        triggerDetail: "manual",
        reason: "retry_failed_run",
        payload,
      });
      if (!("id" in result)) {
        throw new Error(result.message ?? "Retry was skipped.");
      }
      return { newRun: result, originalRun: run };
    },
    onMutate: (run) => {
      setRetryingRunIds((prev) => new Set(prev).add(run.id));
    },
    onSuccess: ({ newRun, originalRun }) => {
      queryClient.invalidateQueries({ queryKey: queryKeys.heartbeats(originalRun.companyId) });
      queryClient.invalidateQueries({ queryKey: queryKeys.heartbeats(originalRun.companyId, originalRun.agentId) });
      navigate(`/agents/${originalRun.agentId}/runs/${newRun.id}`);
    },
    onSettled: (_data, _error, run) => {
      if (!run) return;
      setRetryingRunIds((prev) => {
        const next = new Set(prev);
        next.delete(run.id);
        return next;
      });

View on GitHub (pinned to 01ad858492)

Solutions

  1. Read result.message for the skip reason and address it (unpause agent, free budget).
  2. Refresh the inbox/heartbeats data and retry if the click used stale state.
  3. Confirm the run still exists and is still in a retriable failed state.
  4. Check server logs for the wakeup skip branch for this reason code.

Example fix

// before
if (!("id" in result)) {
  throw new Error(result.message ?? "Retry was skipped.");
}
// after
if (!("id" in result)) {
  setRetryingRunIds((prev) => { const n = new Set(prev); n.delete(run.id); return n; });
  toast.error(result.message ?? "Retry was skipped.");
  throw new Error(result.message ?? "Retry was skipped.");
}
Defensive patterns

Strategy: type-guard

Validate before calling

// refresh inbox/run state before enabling retry
await queryClient.invalidateQueries({ queryKey: ["heartbeats"] });

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 {
  const { newRun } = await retryMutation.mutateAsync(run);
  navigate(`/agents/${newRun.agentId}/runs/${newRun.id}`);
} catch (e) {
  toast.error(e.message);
} finally {
  setRetryingRunIds((prev) => { const n = new Set(prev); n.delete(run.id); return n; });
}

Prevention

When it happens

Trigger: Invoking the inbox retry mutation on a run and receiving a wakeup response without "id" — the backend declined to spawn the retry (agent paused, budget/concurrency gates, run state changed) and returned a message-only payload.

Common situations: Retrying from a stale inbox list after the run was already retried or the agent was paused; on_demand wakeups rejected by server guard rails; the original run was deleted concurrently.

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/7d5579a058a57bac. Report an issue: GitHub.