How automations work
How the Gateway scheduler runs a job, what it keeps between runs, and how a repeated request becomes a stored schedule. Part of the Automations guide.
How automations work
- Automations run inside the Gateway process, not inside the model. The Gateway must be running for schedules to fire.
- Job definitions, runtime state, and run history persist in OpenClaw’s shared SQLite state database, so restarts do not lose schedules.
- Automation runs are recorded in cron run history.
- A run-now request is authorized when it is queued. If it targets the requesting conversation, it starts after that turn ends, using the job’s current scheduled authority. Removing or disabling the job before launch still stops it. Skipped runs and failures before agent execution add a notice to the owning conversation with the reason and the next step.
- Channel-only configuration reloads leave unrelated scheduled runs active. A relevant policy change before execution can re-admit the same occurrence up to twice with a short backoff and fresh authority. Cancellation, revoked job or source authority, and runs that may have performed provider, tool, delivery, or hook work are not replayed by this policy retry. Registered bootstrap hooks conservatively count as possible work even when bootstrap is later skipped.
- Main-session system events use ordinary session admission and remain running until the exact turn settles. A restart before adoption records one interrupted failure; it does not report success or replay the reminder.
- A running automation can remove itself through its scoped automation tool and still finish its final reply. Removing or disabling it from another turn, or pressing Stop, still cancels the active run. Explicitly disabling an already-paused job also cancels a manually forced run; unrelated edits leave that run alone.
- Agent, command, and script jobs write their result once into the chat or topic that receives it, including jobs without a creating conversation. A different delivery destination gets the result instead of the creating chat; without an external route, the creating conversation receives it. Execution context remains separate. See Automation delivery.
- One-shot jobs (
--at) auto-delete after successful completion: delivery is confirmed, not requested, intentionally suppressed, or explicitly best-effort. Failed or unknown required delivery retains the job disabled for inspection without replaying the payload. Pass--keep-after-runto keep successful jobs too. - Per-run runtime budget:
--timeout-secondswhen set. Otherwise, isolated/detached agent-turn jobs are bounded by the scheduler’s own 60-minute watchdog; command jobs default to 10 minutes, and script payloads default to 5 minutes. This scheduler deadline is independent of the per-model-attempt budget (agents.defaults.timeoutSeconds, default 48 hours): starting a fallback does not reset it. Setup, execution, and delivery count toward this deadline, including stalls that never report runner startup. Explicit waits for session or execution lane capacity pause the budget; admission resumes the remaining time. - On Gateway startup, overdue jobs that require agent execution are rescheduled instead of replayed immediately, keeping model/tool execution out of scheduler startup. This includes migrated monitors and main-session system events. Startup catch-up delays survive label or payload-content reconciliation and another restart; changing the schedule starts a new scheduling decision.
- Jobs whose agents are still preparing remain queued without blocking healthy agents. They resume when their Gateway’s preparation finishes.
- A timed job deferred before execution retains its pending occurrence and retries after 30 seconds, doubling the delay up to five minutes. Waiting does not occupy a running slot or change the previous run’s outcome. Job state records the reason, when waiting began, the attempt count, and the next retry; the Automations page shows a warning after five deferred attempts. Retries replace the episode’s unstarted receipt instead of appending skipped receipts. A restart preserves the wait, and completion, cancellation, or a scheduling change clears it.
- Cron slots that pass during a successful or skipped scheduled run are not replayed at restart. Slots missed after that run finishes remain eligible for catch-up. Forced runs still leave their scheduled occurrence pending.
- On a normal scheduler tick, cron jobs can recover a missed slot even if their stored next-run time is in the future, unless
cron.skipMissedJobsis enabled. This recovery does not wake an otherwise idle scheduler before its stored deadline. - When a running Gateway wakes after a deadline, the cron worker coalesces missed timer ticks using its stored deadlines and run requests. The worker owns scheduling, queue capacity, and durable results; the Gateway launches committed requests and joins the worker during shutdown.
- If you drive
openclaw agentfrom system cron or another external scheduler, wrap it with a hard-kill escalation even though the CLI already handlesSIGTERM/SIGINT. Gateway-backed runs ask the Gateway to abort accepted runs;--localruns get the same abort signal. For GNUtimeout, prefertimeout -k 60 600 openclaw agent ...over plaintimeout 600 ...— the-kvalue is the backstop if the process cannot drain in time. For systemd units, use aSIGTERMstop signal with a grace window (TimeoutStopSec) before the final kill. Reusing a--run-idwhile the original Gateway run is still active reports the duplicate as in-flight instead of starting a second run.
Cron owns recovery and history for its own runs; an empty client process is not evidence that a Gateway run has stopped.
The cron worker records execution and primary-delivery outcomes together with job state and history. Post-run notifications happen afterward; a notification failure cannot undo the recorded result.
Restart recovery matches a recorded terminal result to the exact run identity and restores it without running the payload or delivery again. Without a recorded terminal result, an active run becomes interrupted with delivery **Unknown**. An enabled, unchanged, time-scheduled agent-turn job interrupted before delivery gets one fresh retry, including one-shot jobs. The retry restores current job authority and asks the agent to reconcile prior work before continuing; arbitrary interrupted tool effects are not guaranteed exactly once. Possible prior delivery, command/script payloads, and event or process-exit schedules are not automatically replayed. Inspect their history and recipient before retrying manually. An early manual run preserves its separate scheduled occurrence even if it waited past that deadline before starting. The interrupted manual run is still failed and is not retried. A separately rescheduled one-shot keeps its new occurrence.
Recurring restart retries retain the existing error-backoff floor, and their saved next-run time includes that delay. The interruption does not increase the failure streak. One-shot restart retries retain their short refire delay.
Queued timed requests can resume after restart. Queued manual or event requests whose transient payload was lost record a skipped outcome instead of reconstructing the payload. Catch-up limits and delays still pace overdue scheduling. A terminal result with `deleteAfterRun` deletes the job only when completion is `succeeded`.
If a completed run's history was saved but its job update failed, a later acknowledged schedule or pacing edit keeps its next check through recovery. Recovery retains the completed history and settles the old run without executing its payload again. Saving an unchanged schedule does not change how that completed run is recovered.
Interrupted runs appear as failures in run history. Recovering the same interruption again does not add another history entry.
Promoting a repeated job into an automation
Most automations should start as work the agent already did. When you ask for substantially the same job several times, the agent offers to turn it into a schedule instead of only running it once more. Promotion is preferred over building a job from scratch because the proposal inherits a run you already read: you know what the output looks like before it starts arriving on a schedule.
There is no repetition-detection engine and no new stored history. The agent
recognizes the repeat from the conversation itself and checks
automations(action: "list") for an existing job before proposing a new one,
so a routine you already created is not duplicated. The prompt includes this
guidance when the automations tool is available and tells the agent to offer
promotion only when its current actions include list, add, run, and
remove. Read-only recovery and other restricted tool variants do not support
this workflow. This is model guidance; tool policy and approvals still govern
the actions.
The confirmation restates the schedule and the task in plain words before anything is created, for example: “Every weekday at 07:00 Europe/Vienna, I summarize overnight updates and post them here.” Confirm that sentence, not a cron expression.
On confirmation the agent:
- Creates the job, with delivery defaulting to the conversation where you asked: its channel and thread, or a conversation commit when there is no external route.
- Immediately runs it once with
runinforcemode as a visible test, delivered to that same conversation, so you see real output well before the first scheduled occurrence. - Removes the job and tells you if that test fails.
The job is created enabled, not disabled-pending-approval, and that is a
deliberate safety choice. The scheduler supervises enabled jobs: a failing one
raises a failure notification and is auto-disabled after repeated errors, with
the reason recorded and the owner notified. Nothing supervises a disabled job.
A job left disabled waiting for a confirmation that never arrives is invisible
to every guard, hidden from the default automations list, and will never fire
or explain itself — a silent non-outcome, which is a worse failure than a job
that runs and visibly complains.
Your confirmation still gates creation, so nothing is scheduled behind your back, and the test run is a real run with real delivery rather than a rendered preview: what you approve is exactly what the schedule will produce.