---
name: cronjob
description: "Scheduling and managing recurring tasks via Hermes cron. Covers schedule formats, job creation, execution patterns, and best practices."
version: 1.0.0
author: Hermes Agent
license: MIT
metadata:
  hermes:
    tags: [cron, scheduling, automation, recurring]
---

# Cron Job Management

Manage recurring scheduled tasks in Hermes via the cron system. Drive via the `cronjob` tool, the `hermes cron` CLI, or the `/cron` slash command.

## When to Use

- **Recurring data collection:** Weather checks, inbox monitoring, system health checks
- **Scheduled briefings:** Daily morning briefings, weekly reports
- **Periodic maintenance:** Log rotation, database cleanup, cache invalidation
- **Time-based triggers:** Reminders, check-ins, automated notifications

## Schedule Formats

### Interval-based (recommended for simple recurring tasks)
```
every 2h       # Every 2 hours
every 30m      # Every 30 minutes
daily          # Once per day
weekly         # Once per week
```

### Standard cron (5-field)
```
0 5 * * *     # Daily at 05:00
0 9 * * 1     # Every Monday at 09:00
```

## Important Notes

- **Range syntax like `07-19 * * *` is NOT supported.** Hermes cron does not parse range expressions. Use interval-based syntax instead.
- **Timezone:** Cron schedules use `Europe/Berlin` (UTC+2 summer, UTC+1 winter) by default.
- **Next run calculation:** Hermes calculates the next run time based on the current timezone.

## Job Structure

Each cron job has:
- `job_id`: Unique identifier
- `prompt`: The instruction template
- `schedule`: Cron expression or interval
- `repeat`: Number of times to repeat
- `deliver`: Delivery target (e.g., `origin` for Telegram)
- `model`: Model to use for LLM-based jobs
- `enabled`: Boolean state

## Best Practices

1. **Use scripts for complex jobs:** Write a Python script in `~/.hermes/scripts/` and invoke it from the cron prompt.
2. **Use interval syntax for regular checks:** `every 2h` is simpler and more reliable than complex cron expressions.
3. **Use cron syntax for specific times:** `0 5 * * *` for "daily at 05:00". Multiple times: `0 9,21 * * *` for 09:00 and 21:00.
4. **Test with `hermes cron run <job_id>`** before relying on scheduled execution.
5. **Monitor with `hermes cron list`** to verify next run times.
6. **Match stdout to the delivery audience:** for `no_agent=True` jobs delivered to the user, stdout is sent verbatim. Do not dump raw JSON/status objects unless the user explicitly asked for machine output. Wrap script output into short plain-language bullets with only the fields the user needs; reserve raw JSON for `deliver='local'` collectors or debugging jobs.
- **Cron create requires `schedule` parameter:** When creating jobs, always provide a valid `schedule` field (cron expression like `0 9,21 * * *` or interval like `every 2h`). The `schedule` field is mandatory for `cronjob` create action.
- **Script paths must be relative to `~/.hermes/scripts/`:** Pass just the filename (e.g. `yazio_sync.py`), NOT the full path. The cron system resolves relative to `~/.hermes/scripts/`.
- **Provider/auth failures are often job-level, not script-level:** If a script-backed job fails with an LLM `RuntimeError` such as `401 User not found`, inspect the job's `provider`/`model`, `~/.hermes/auth.json` status, and the latest `~/.hermes/cron/output/<job_id>/*.md` before debugging the script. A minimal fix can be to switch that job to a known-good provider/model, then trigger it and verify `Last run ... ok`.

## Conditional Execution Pattern

For jobs that should only run when certain conditions are met (e.g., only when data exists):

```python
# Im Cron-Prompt:
1. Prüfe Bedingung (z.B. DB-Einträge für heute)
2. Wenn 0 Einträge → silent exit (keine Antwort)
3. Wenn Einträge vorhanden → führe Aufgabe aus
```

**Beispiel:** Täglicher Ernährungsstrategie-Check — prüft ob Ernährungseinträge existieren, erstellt nur bei Vorhandensein einen Bericht.

**Vorteil:** Kein Spam wenn User nichts einträgt. Nur relevante Berichte.

## OpenClaw vs Hermes Config

- **OpenClaw** (`~/.openclaw/`) und **Hermes** (`~/.hermes/`) haben getrennte Configs
- `openclaw config get/set` liest/schreibt OpenClaw Config
- `hermes config get/set` liest/schreibt Hermes Config
- **STT/TTS Config** liegt in `~/.hermes/config.yaml` — verwende `hermes config` oder direkte YAML-Editierung
- **Gateway-Neustart:** `openclaw gateway restart` (OpenClaw Gateway)
- **Config-Persistenz:** YAML-Editionen via Python können stillschweigend fehlschlagen — immer mit separatem Read-Back verifizieren

## Linked Resources

- `references/cron-scheduling-patterns.md` — Schedule format examples and use cases from sessions.
- `references/morning-briefing-delivery.md` — Pattern for delivering cron-generated briefings to Telegram (token discovery, MarkdownV2 escaping).
- `references/morning-briefing-context.md` — JSON collector pattern for grounded daily briefings with Calendar, Todoist, weather, commute, traffic, health context, and news.
- `references/model-auth-failures.md` — Troubleshooting pattern for cron jobs that fail because the configured LLM provider/model auth is invalid or exhausted, including safe verification without printing secrets.
- `references/provider-auth-troubleshooting.md` — Workflow for diagnosing cron failures caused by provider/auth errors such as OpenRouter `401 User not found`.
