paperclipai/paperclip · error

Resume request was skipped.

Error message

Resume request was skipped.

What it means

After calling agentsApi.wakeup to resume a run whose process was lost, the code checks whether the response looks like a run (has an "id"). If it does not, the API declined to resume and returned only a message; this error is thrown with the server-provided message, defaulting to "Resume request was skipped." It surfaces a server-side skip decision (e.g. guard rails in the wakeup handler) to the UI.

Source

Thrown at ui/src/pages/AgentDetail.production.tsx:3294

    const taskId = asNonEmptyString(context.taskId);
    const taskKey = asNonEmptyString(context.taskKey);
    const commentId = asNonEmptyString(context.wakeCommentId) ?? asNonEmptyString(context.commentId);
    if (issueId) payload.issueId = issueId;
    if (taskId) payload.taskId = taskId;
    if (taskKey) payload.taskKey = taskKey;
    if (commentId) payload.commentId = commentId;
    return payload;
  }, [run.contextSnapshot, run.id]);
  const resumeRun = useMutation({
    mutationFn: async () => {
      const result = await agentsApi.wakeup(run.agentId, {
        source: "on_demand",
        triggerDetail: "manual",
        reason: "resume_process_lost_run",
        payload: resumePayload,
      }, run.companyId);
      if (!("id" in result)) {
        throw new Error(result.message ?? "Resume request was skipped.");
      }
      return result;
    },
    onSuccess: (resumedRun) => {
      queryClient.invalidateQueries({ queryKey: queryKeys.heartbeats(run.companyId, run.agentId) });
      navigate(`/agents/${agentRouteId}/runs/${resumedRun.id}`);
    },
  });

  const canRetryRun = run.status === "failed" || run.status === "timed_out";
  const retryPayload = useMemo(() => {
    const payload: Record<string, unknown> = {};
    const context = asRecord(run.contextSnapshot);
    if (!context) return payload;
    const issueId = asNonEmptyString(context.issueId);
    const taskId = asNonEmptyString(context.taskId);
    const taskKey = asNonEmptyString(context.taskKey);
    if (issueId) payload.issueId = issueId;

View on GitHub (pinned to 01ad858492)

Solutions

  1. Read the accompanying server message (result.message) for the concrete skip reason and address it.
  2. Refresh the run/heartbeat data and retry the resume if the state was stale.
  3. Check agent pause/concurrency/budget gates in the UI and lift them before resuming.
  4. Inspect server logs for the wakeup handler's skip branch to confirm why no run was created.

Example fix

// before
if (!("id" in result)) {
  throw new Error(result.message ?? "Resume request was skipped.");
}
// after (caller-side narrowing before throwing)
if (!("id" in result)) {
  toast.error(result.message ?? "Resume request was skipped.");
  await queryClient.invalidateQueries({ queryKey: queryKeys.heartbeats(run.companyId, run.agentId) });
  return;
}
Defensive patterns

Strategy: type-guard

Validate before calling

// nothing to validate client-side pre-call; refresh run state first
await queryClient.invalidateQueries({ queryKey: queryKeys.heartbeats(companyId, agentId) });

Type guard

const isResumedRun = (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 run = await resumeRun.mutateAsync();
  navigate(`/agents/${agentRouteId}/runs/${run.id}`);
} catch (e) {
  toast.error(e.message);
  await queryClient.invalidateQueries({ queryKey: queryKeys.heartbeats(companyId, agentId) });
}

Prevention

When it happens

Trigger: agentsApi.wakeup(..., { reason: "resume_process_lost_run", ... }) resolves with a payload lacking an "id" field — the backend skipped the wakeup (e.g. run no longer eligible, agent busy, stale run) and returned { message: ... } or a non-run object.

Common situations: The run was concurrently picked up or cancelled elsewhere; the agent has a max-concurrency or pause gate blocking on_demand wakeups; the run record transitioned between page load and the resume click; backend validation rejects the resume but returns 200 with a message.

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