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.

5 min readSume
All posts

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 on a Sume schedule's API trigger. Source: Sume docs, read 2026-10-04.
on_active_runHTTP resultRun recordedUse it when
skip (default)200 with status skipped, skip_reason previous_run_activeYesOverlapping triggers are expected and harmless
reject409 action_run_in_progressNoA 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

All Agents posts

Written by Sume