NousResearch/hermes-agent · error · ValueError
Cron expressions require 'croniter' package. Install with: p
Error message
Cron expressions require 'croniter' package. Install with: pip install croniter
What it means
ValueError raised in parse_schedule: the string was classified as a cron expression (5+ space-separated fields all matching ^[\d*\-,/]+$), but the croniter package needed to validate cron expressions is not installed and could not be auto-ensured by _ensure_croniter(). Interval and ISO-timestamp schedules do not need croniter; only the cron-expression branch does.
Source
Thrown at cron/jobs.py:651
# "every X" pattern → recurring interval
if schedule_lower.startswith("every "):
duration_str = schedule[6:].strip()
minutes = parse_duration(duration_str)
return {
"kind": "interval",
"minutes": minutes,
"display": f"every {minutes}m"
}
# Check for cron expression (5 or 6 space-separated fields)
# Cron fields: minute hour day month weekday [year]
parts = schedule.split()
if len(parts) >= 5 and all(
re.match(r'^[\d\*\-,/]+$', p) for p in parts[:5]
):
if not _ensure_croniter():
raise ValueError("Cron expressions require 'croniter' package. Install with: pip install croniter")
# Validate cron expression
try:
croniter(schedule)
except Exception as e:
raise ValueError(f"Invalid cron expression '{schedule}': {e}")
return {
"kind": "cron",
"expr": schedule,
"display": schedule
}
# ISO timestamp (contains T or looks like date)
if 'T' in schedule or re.match(r'^\d{4}-\d{2}-\d{2}', schedule):
try:
# Parse and validate
dt = datetime.fromisoformat(schedule.replace('Z', '+00:00'))
# Make naive timestamps timezone-aware at parse time so the stored
# value doesn't depend on the system timezone matching at check time.View on GitHub (pinned to c896c09c42)
Solutions
- Install croniter into the running interpreter: pip install croniter
- If you cannot install, use an equivalent the parser supports without croniter, e.g. an ISO one-shot timestamp — though for recurring schedules croniter is effectively required
Example fix
# before create_job(schedule="0 9 * * *") # ValueError: Cron expressions require 'croniter' package. # after python -m pip install croniter create_job(schedule="0 9 * * *")
Defensive patterns
Strategy: fallback
Validate before calling
import importlib.util
def croniter_available() -> bool:
return importlib.util.find_spec("croniter") is not None
if not croniter_available() and looks_like_cron(expr):
raise SystemExit("pip install croniter (required for cron expressions)") Try / catch
try:
parsed = parse_schedule("0 9 * * *")
except ValueError as e:
if "croniter" in str(e):
subprocess.run([sys.executable, "-m", "pip", "install", "croniter"], check=True)
parsed = parse_schedule("0 9 * * *")
else:
raise Prevention
- Install croniter in any deployment that accepts cron expressions
- Pre-check find_spec('croniter') when the schedule has 5+ cron-ish fields
- Keep croniter in the pinned requirements so slim installs don't drop it
When it happens
Trigger: create_job(schedule='0 9 * * *') in an environment where croniter is absent (not in requirements, stripped slim install, or a broken import caught by _ensure_croniter).
Common situations: Minimal/slim deployments that excluded the optional croniter dependency; a corrupted venv; croniter removed during an upgrade.
Related errors
- a time is required
- unknown recurrence {preset!r} — one of {', '.join(WEEKDAY_PR
- unknown day {day!r}
- Preview mode — launching is disabled.
- no install root
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/de7ad20cbff168ba.
Report an issue: GitHub.