Sume scheduled run returned skipped: detect previous_run_active
A Sume scheduled run that overlaps another returns 200 with status skipped, not an error. Check skip_reason in code, and choose reject if a drop must be loud.

A skipped scheduled run is a success response. When a run is already active and on_active_run is skip, which is the default for scheduled runs, Sume returns 200 with a receipt whose status is skipped and whose skip_reason is previous_run_active. If your code only checks for a 2xx, you will treat a dropped trigger as a launched one (Sume docs: Trigger a schedule by API, read 2026-10-06).
Check the status field, not just the HTTP code, and decide whether a skip is acceptable for that job.
What the two policies return
With skip, the API records a run row and answers 200. With reject, it records no run and answers 409 action_run_in_progress. The same 200 is also used for an idempotency replay, so a 200 can mean either 'this was skipped' or 'I have seen this key before'. The receipt tells you which: a replay carries idempotency_hit true, a skip carries status skipped.
Use skip when overlap is expected and harmless, such as a frequent refresh where the next tick will catch up. Use reject when a dropped trigger must surface as an error in your caller, such as a once-a-day report you promised to a person.
Handle all three outcomes
The script below fires a trigger and branches on the three results. Keep the Idempotency-Key between 1 and 255 characters, and derive it from the business event, like the date, so a retry replays rather than duplicates.
import os, requests
H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
"Idempotency-Key": "weekly-recap-2026-10-06"}
url = "https://api.sume.com/v1/actions/acme/weekly-recap/runs"
r = requests.post(url, json={"on_active_run": "reject"},
headers=H, timeout=30)
if r.status_code == 409:
print("previous run still active: alert a human")
elif r.status_code in (200, 202):
d = r.json()["data"]
if d.get("status") == "skipped":
print("skipped:", d.get("skip_reason"))
elif d.get("idempotency_hit"):
print("replay of an earlier run")
else:
print("started", d["id"])
else:
print(r.status_code, r.text[:200])Why runs overlap in the first place
Overlap usually means a run is slower than its interval, or a manual trigger landed on top of a scheduled one. Read the receipt of the run that is holding the slot before you blame the trigger. If runs routinely outlast the interval, lengthen the interval rather than relying on skips to hide the problem.
Scheduled runs are read at /v1/action-runs/{id} and carry their own statuses (queued, processing, completed, failed, canceled, skipped), so build your monitoring around the receipt route.
| Situation | HTTP | Signal in body |
|---|---|---|
| Started | 202 | status queued |
| Skipped, skip policy | 200 | status skipped, skip_reason previous_run_active |
| Rejected, reject policy | 409 | error action_run_in_progress |
| Idempotency replay | 200 | idempotency_hit true |
Alert on repeated skips
One skip is noise. Three in a row is a pattern. Count consecutive skipped receipts per schedule and alert when the count passes a threshold you choose. That turns a silent failure mode into a visible one without making every overlap an error.
Choosing the policy per schedule
There is no single right answer for on_active_run. A refresh that runs every few minutes should skip, because the next one will cover it. A promised daily deliverable should reject, because a skipped run means a missed delivery and you want to know. Write the choice and the reason next to each trigger in your code.
Remember that the default for Format runs is allow, which lets overlapping runs both proceed, and that bulk queue items always run with allow. Skip and reject are specific to schedule triggers and single run calls where you set them.
Sources
Related posts
More in Agents
- Did my Sume cron schedule fire? Read last_run_at and next_run_at
GET /v1/actions/{id} returns last_run_at and cron.next_run_at. Compare them with the run list to see if a schedule fired, without opening the dashboard.
- Sume schedule slug rules: 2-64 characters, and runs is reserved
A Sume schedule slug is lowercase alphanumerics with single hyphens, 2 to 64 characters, unique in your account. The word runs is reserved. See the vanity path.
- trending-research_search MCP tool: Reels and TikTok trends, $0.10
The hosted MCP tool trending-research_search finds trending Instagram Reels and TikTok videos for a niche at about $0.10 per search. YouTube is not supported.
- Trim pauses from ten clips: inspect segments, then one timeline render
Rough-cut apps trim pauses in their own editor. For a batch by API, inspect each clip for sentence segments, keep the speech, and render one timeline.
Written by Sume