Hermes cron fixes for run now, and Sume's one-active-run rule
Hermes fixed run-now cancelling the next scheduled run. Sume schedules allow one active run: a second is skipped, or rejected if you ask for reject.

Hermes Agent's September 11, 2026 release fixed two cron edge cases: an off-tick run-now no longer cancels the next scheduled run, and a killed manual run no longer blocks the next one for five minutes (release notes, read 2026-10-04). Sume handles the same collision with a simple rule. Only one run of a schedule is active at a time, and a run that arrives while another is active is skipped, or rejected if you set on_active_run to reject.
What Sume does when two runs collide
On the API trigger, the on_active_run field decides. The default is skip: the call returns 200 with a receipt whose status is skipped and whose skip_reason is previous_run_active, and a run row is recorded. With reject, the call returns 409 action_run_in_progress and no run is recorded (run a schedule via API).
| on_active_run | HTTP result | Run recorded | Use it when |
|---|---|---|---|
| skip (default) | 200 with status skipped, skip_reason previous_run_active | Yes | Overlapping triggers are expected and harmless |
| reject | 409 action_run_in_progress | No | A dropped trigger should surface as an error in your caller |
What that means for a manual run during a cron window
A run started by hand while a cron run is active does not cancel the cron run and does not queue behind it: under the default it is recorded as skipped and returns right away. A run row records its trigger source as cron, manual or api, so history shows who started each one.
A skipped run never sends a webhook, because no work started. Read the status on the response instead of waiting for a POST.
Handle the skip in your caller
When you start runs from code, check the status on the response. If it is skipped, wait for the active run to finish and try again, rather than treating 200 as success.
import os, requests
key = os.environ.get("SUME_API_KEY")
action = os.environ.get("ACTION_ID")
if not key or not action:
raise SystemExit("set SUME_API_KEY and ACTION_ID")
r = requests.post(
f"https://api.sume.com/v1/actions/{action}/runs",
headers={"Authorization": f"Bearer {key}", "Idempotency-Key": "nightly-2026-10-04"},
json={"on_active_run": "skip"},
timeout=30,
)
body = r.json()
data = body.get("data", body)
if data.get("status") == "skipped":
print("skipped:", data.get("skip_reason"))
else:
print(r.status_code, data.get("status"))Keep a retry from duplicating work
Send an Idempotency-Key on each start. Replaying a key returns the original receipt with idempotency_hit set, and reusing it with a different payload returns 409 idempotency_conflict. The key plus the one-active-run rule means a double click or a retry loop cannot start two paid runs of the same schedule.
Sources
Related posts
More in Agents
- Kilo scheduled sessions vs a Sume schedule for recurring renders
Kilo v7.8.3 reports a session waiting on a wakeup or cron task as scheduled. A Sume schedule lives server-side; use it when renders must run unattended.
- OpenAI Dots x Runway: brief a dot, it plans shots. The Sume loop
Runway's Oct 1 changelog lists OpenAI Dots x Runway for all plans: brief a dot, it plans shots, Runway shoots. The same loop with Sume MCP tools.
- Qwen3.8-Omni-Flash for audio agents: tool access
Qwen3.8-Omni-Flash is an omnimodal model for agents. Whatever model you pick, give it Sume's hosted MCP tools and check tools_list before any paid call.
- Run the Sume video agent from your backend with Agent Completions
POST /v1/agent/completions runs the same agent as the Sume Agents chat, with tools and media generation, and returns an async run receipt you poll or webhook.
Written by Sume