Skip to content

fix(cronjob): accept schedule param aliases (cron, when, ...) (#34120) - #53246

Closed
teknium1 wants to merge 2 commits into
mainfrom
hermes/hermes-7777455c
Closed

fix(cronjob): accept schedule param aliases (cron, when, ...) (#34120)#53246
teknium1 wants to merge 2 commits into
mainfrom
hermes/hermes-7777455c

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

cronjob(action=create) now accepts the schedule under common synonym keys some models emit (cron, when, cron_expression, …) instead of failing with "schedule is required for create" — fixes #34120.

Root cause: the handler lambda read every argument by its exact canonical key (args.get("schedule")). Models that emitted the cron expression under cron/when, or set schedule="" alongside cron="0 9 * * *", hit the missing-schedule rejection even though a valid schedule was present in the same tool call.

Changes

  • tools/cronjob_tools.py: add _coalesce_arg() + _CRONJOB_ARG_ALIASES; rewire the registry handler lambda to coalesce aliases for schedule, prompt, job_id, deliver, skills, enabled_toolsets, no_agent. Canonical key always wins; empty/None falls through to aliases. Missing-schedule error now lists accepted aliases + examples.
  • Follow-up: dropped "message" from the prompt alias set — too generic a key to safely map onto the cron prompt. instruction/task retained.
  • tests/tools/test_cronjob_tools.py: coalesce-precedence, per-alias, empty-string fall-through, scoping, and error-message tests.

Validation

Tool call Before After
schedule="..." created created
cron="..." "schedule is required" created
schedule="" , cron="..." "schedule is required" created
when="every 2h" "schedule is required" created
message → prompt n/a not coalesced (dropped)

Live before/after verified through the real registry.dispatch path against a temp HERMES_HOME (no mocks). Targeted suite: 79/79 pass.

Salvaged from #34255 by @Bartok9 — his authorship preserved via cherry-pick. Supersedes #49792 (which made schedule/job_id globally required in the schema — incorrect, since those are action-specific and would break every list/remove/pause/resume/run call).

Infographic

infographic

Bartok9 and others added 2 commits June 26, 2026 12:52
Fixes #34120. The 'cronjob' tool consistently rejected create calls with
'schedule is required for create' even when the user/agent included a
schedule parameter — because the model (notably grok-4.3 on Discord)
emitted the parameter under a non-canonical name like 'cron',
'cron_expression', or 'when' that the handler's args.get('schedule')
lookup didn't see.

Fix: add a _coalesce_arg helper that maps common synonym keys to the
canonical kwargs at the registry handler boundary. Synonyms accepted:

  schedule  ← cron, cron_expression, cron_schedule, when, time,
              frequency, interval
  prompt    ← instruction, task, message
  job_id    ← id, jobId, cron_id
  deliver   ← delivery, deliver_to, destination, target
  skills    ← skill_list, skill_names
  enabled_toolsets ← toolsets, tools
  no_agent  ← script_only, no_llm

Canonical always wins when present (and non-empty/None) so this is
non-breaking. Empty-string or null canonical falls through to alias
lookup, covering the grok-4.3 case where the model emits BOTH
schedule='' AND cron='0 9 * * *' in the same tool call.

Also improves the missing-schedule error message to list accepted
aliases inline so user/agent can self-debug without grepping source.

Adds 11 alias-coalesce tests + 1 error-message test in two new classes:
TestCoalesceArgAliases (10) and TestCronjobMissingScheduleErrorMessage (1).

All 68 tests in test_cronjob_tools.py pass.

Co-authored-by: Cursor <cursoragent@cursor.com>
Follow-up to the #34120 alias-coalescing salvage. "message" is too
generic a key to safely map onto the cron prompt — a model can emit it
meaning something unrelated. The remaining "instruction"/"task" aliases
are unambiguous. Canonical "prompt" still always wins.
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-7777455c vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 11493 on HEAD, 11493 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 6039 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cron Cron scheduler and job management labels Jun 26, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Salvage of #34255 (@Bartok9) onto current main; fixes #34120 and supersedes #49792. Marked related_to those, not duplicate.

@Bartok9

Bartok9 commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Thanks for rebasing this onto main and keeping the attribution — appreciated. The alias-normalization approach here matches the intent of #34255; happy to see it land against current main. LGTM from my side.

@alt-glitch alt-glitch added the comp/tools Tool registry, model_tools, toolsets label Jun 26, 2026
@teknium1

Copy link
Copy Markdown
Contributor Author

Closing — we don't add alias/synonym coverage to work around models emitting tool-call arguments under the wrong key.

The schema declares the parameter as schedule. A model emitting the value under cron/when/cron_expression (or schedule="" plus the real value elsewhere) is a model schema-compliance failure, not a Hermes bug. Building a coalescing layer to accept every synonym a given model happens to produce is open-ended, grows with every model, and masks the actual problem instead of surfacing it. The "schedule is required for create" rejection is correct behavior.

Appreciate the work, @Bartok9 — this just isn't a direction we take.

@teknium1 teknium1 closed this Jun 27, 2026
@teknium1
teknium1 deleted the hermes/hermes-7777455c branch June 27, 2026 06:49
@Bartok9

Bartok9 commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Completely fair call, and thanks for taking the time to explain the reasoning rather than just closing it — that's appreciated.

You're right: a model emitting the value under the wrong key is a schema-compliance failure on the model's side, and a coalescing layer that accepts every synonym would be open-ended and would mask the real problem instead of surfacing it. Failing loudly with "schedule is required" is the correct behavior. I'd rather the schema stay strict than grow an ever-expanding compatibility shim.

Appreciate the clear philosophy — it'll sharpen what I bring next. Thanks again 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management comp/tools Tool registry, model_tools, toolsets P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: cronjob tool: create action always fails with "schedule is required for create" even when parameters are provided

3 participants