Skip to content

[Bug]: Cron jobs never run or when it failed, no useful information is recorded #2788

@Celthi

Description

@Celthi

Bug Description

The hermes code commit
commit 6302e56 (HEAD -> main, origin/main, origin/HEAD)
Author: Teknium 127238744+teknium1@users.noreply.github.com
Date: Mon Mar 23 07:19:14 2026 -0700

I have used it to create a cron job yesterday, but today when I'm back to work, I reviewed the cron job and it seems it never fires.
The next_run_at for the cron job is still the timestamp from yesterday. From the following chat history, we can see it never run

{
"role": "user",
"content": "a cron job approach"
},
{
"role": "assistant",
"content": "",
"reasoning": "The user wants a cron job that watches the PR and merges when CI passes. Let me set this up.",
"finish_reason": "tool_calls",
"tool_calls": [
{
"id": "call_function_zlhrj4pip03g_1",
"call_id": "call_function_zlhrj4pip03g_1",
"response_item_id": "fc_function_zlhrj4pip03g_1",
"type": "function",
"function": {
"name": "cronjob",
"arguments": "{"action": "create", "prompt": "Check the CI status of PR 11326 on repo. If all status checks pass and the PR is mergeable, merge it using: gh pr merge 11326 --repo repo --squash --delete-branch. If CI is still running, do nothing. If CI failed, alert that it failed. Use gh pr view 11326 --repo repo --json state,mergeable,statusCheckRollup,mergeStateStatus to check status.", "schedule": "15m", "name": "Merge PR 11326 when CI passes", "repeat": 72}"
}
}
]
},
{
"role": "tool",
"content": "{\n "success": true,\n "job_id": "2555d8919a51",\n "name": "Merge PR 11326 when CI passes",\n "skill": null,\n "skills": [],\n "schedule": "once in 15m",\n "repeat": "72 times",\n "deliver": "local",\n "next_run_at": "2026-03-23T18:13:37.833274-04:00",\n "job": {\n "job_id": "2555d8919a51",\n "name": "Merge PR 11326 when CI passes",\n "skill": null,\n "skills": [],\n "prompt_preview": "Check the CI status of PR 11326 on repo. If all status checks pass and the PR is mergeab...",\n "model": null,\n "provider": null,\n "base_url": null,\n "schedule": "once in 15m",\n "repeat": "72 times",\n "deliver": "local",\n "next_run_at": "2026-03-23T18:13:37.833274-04:00",\n "last_run_at": null,\n "last_status": null,\n "enabled": true,\n "state": "scheduled",\n "paused_at": null,\n "paused_reason": null\n },\n "message": "Cron job 'Merge PR 11326 when CI passes' created."\n}",
"tool_call_id": "call_function_zlhrj4pip03g_1"
},
{
"role": "assistant",
"content": "Done. Cron job 2555d8919a51 is running:\n\n- Schedule: every 15 minutes, up to 72 runs (~18 hours)\n- Logic: checks CI status; merges with --squash --delete-branch if all pass; alerts on failure; does nothing if still running\n- Delivery: local (you'll see the result here)\n\nYou'll get a message when it merges or when things go sideways. If CI hasn't passed within ~18 hours it'll stop retrying — let me know if that happens and we can extend it.",
"reasoning": "The cron job is set up. It will check every 15 minutes for up to 72 times (72 * 15 min = 18 hours). Let me confirm the details to the user.",
"finish_reason": "stop"
},

{
"role": "user",
"content": "show me the cron jobs and when it will run"
},
{
"role": "assistant",
"content": "",
"reasoning": "Just list the cron jobs.",
"finish_reason": "tool_calls",
"tool_calls": [
{
"id": "call_function_bhejytrrbmmv_1",
"call_id": "call_function_bhejytrrbmmv_1",
"response_item_id": "fc_function_bhejytrrbmmv_1",
"type": "function",
"function": {
"name": "cronjob",
"arguments": "{"action": "list", "include_disabled": true}"
}
}
]
},
{
"role": "tool",
"content": "{\n "success": true,\n "count": 1,\n "jobs": [\n {\n "job_id": "2555d8919a51",\n "name": "Merge PR 11326 when CI passes",\n "skill": null,\n "skills": [],\n "prompt_preview": "Check the CI status of PR 11326 on repo using: gh pr view 11326 --repo repo ...",\n "model": null,\n "provider": null,\n "base_url": null,\n "schedule": "once in 15m",\n "repeat": "72 times",\n "deliver": "local",\n "next_run_at": "2026-03-23T18:13:37.833274-04:00",\n "last_run_at": null,\n "last_status": null,\n "enabled": true,\n "state": "scheduled",\n "paused_at": null,\n "paused_reason": null\n }\n ]\n}",
"tool_call_id": "call_function_bhejytrrbmmv_1"
},
{
"role": "assistant",
"content": "One cron job:\n\n| | |\n|---|---|\n| Name | Merge PR 11326 when CI passes |\n| ID | 2555d8919a51 |\n| Schedule | every 15 minutes |\n| Repeats | 72 times (~18 hours total) |\n| Next run | 2026-03-23 18:13:37 EDT |\n| Status | scheduled |\n| Delivery | local |",
"reasoning": "Let me format this nicely for the user.",
"finish_reason": "stop"
},
{
"role": "user",
"content": "what is the time now"
},
{
"role": "assistant",
"content": "",
"reasoning": "The user wants to know the current time.",
"finish_reason": "tool_calls",
"tool_calls": [
{
"id": "call_function_s3psl2fj7t7v_1",
"call_id": "call_function_s3psl2fj7t7v_1",
"response_item_id": "fc_function_s3psl2fj7t7v_1",
"type": "function",
"function": {
"name": "terminal",
"arguments": "{"command": "date"}"
}
}
]
},
{
"role": "tool",
"content": "{"output": "Tue Mar 24 09:02:43 EDT 2026", "exit_code": 0, "error": null}",
"tool_call_id": "call_function_s3psl2fj7t7v_1"
},
{
"role": "assistant",
"content": "It's March 24, 09:02 EDT — the next scheduled run was March 23 18:13, so we're well past that. Let me check the CI status and see if the job has been running.",
"reasoning": "So the next run was supposed to be at 18:13 EDT on March 23, but it's now March 24 09:02 EDT. That's about 15 hours after the scheduled next run. The cron job should have run many times by now. Let me check the current CI status and see what's happening.",
"finish_reason": "tool_calls",
"tool_calls": [
{
"id": "call_function_zwo3bs4sjb6c_1",
"call_id": "call_function_zwo3bs4sjb6c_1",
"response_item_id": "fc_function_zwo3bs4sjb6c_1",
"type": "function",
"function": {
"name": "terminal",
"arguments": "{"command": "GITHUB_TOKEN='<<' gh pr view 11326 --repo repo --json state,mergeable,statusCheckRollup,mergeStateStatus --jq '.statusCheckRollup[] | \"\\(.context) (\\(.state))\"'"}"
}
}
]
},
{
"role": "tool",
"content": "{"output": "premerge-linux-m2021 (PENDING)\nnull (null)\nIs valid Jira item in the PR title? (SUCCESS)\nIs valid Readme in the repository? (SUCCESS)\npremerge-header-generator-m2021 (SUCCESS)\npremerge-ios-dossier-m2021 (SUCCESS)\npremerge-ios-platform-m2021 (SUCCESS)\npremerge-win32-m2021 (SUCCESS)\npremerge-win64-m2021 (SUCCESS)", "exit_code": 0, "error": null}",
"tool_call_id": "call_function_zwo3bs4sjb6c_1"
},
{
"role": "assistant",
"content": "",
"reasoning": "The cron job's next_run was in the past (2026-03-23 18:13:37 EDT), and we're now at 2026-03-24 09:02 EDT. The premerge-linux-m2021 is still PENDING. Let me check if the cron job has been running at all.",
"finish_reason": "tool_calls",
"tool_calls": [
{
"id": "call_function_w259bddss0j5_1",
"call_id": "call_function_w259bddss0j5_1",
"response_item_id": "fc_function_w259bddss0j5_1",
"type": "function",
"function": {
"name": "cronjob",
"arguments": "{"action": "list", "include_disabled": true}"
}
}
]
},
{
"role": "tool",
"content": "{\n "success": true,\n "count": 1,\n "jobs": [\n {\n "job_id": "2555d8919a51",\n "name": "Merge PR 11326 when CI passes",\n "skill": null,\n "skills": [],\n "prompt_preview": "Check the CI status of PR 11326 on repo using: gh pr view 11326 --repo repo ...",\n "model": null,\n "provider": null,\n "base_url": null,\n "schedule": "once in 15m",\n "repeat": "72 times",\n "deliver": "local",\n "next_run_at": "2026-03-23T18:13:37.833274-04:00",\n "last_run_at": null,\n "last_status": null,\n "enabled": true,\n "state": "scheduled",\n "paused_at": null,\n "paused_reason": null\n }\n ]\n}",
"tool_call_id": "call_function_w259bddss0j5_1"
},
{
"role": "assistant",
"content": "The cron hasn't fired at all yet — last_run_at is null and next_run_at is still stuck at yesterday's 18:13. The scheduler appears to be dormant. Let me recreate it with a fresh schedule.",
"reasoning": "The cron job hasn't run at all (last_run_at is null). It seems the cron scheduler isn't working properly - the next_run_at was in the past (March 23 18:13) but the job hasn't fired since then. Let me remove this job and create a new one with a fresh schedule.",
"finish_reason": "tool_calls",
"tool_calls": [
{
"id": "call_function_5mv5ncy4ch8g_1",
"call_id": "call_function_5mv5ncy4ch8g_1",
"response_item_id": "fc_function_5mv5ncy4ch8g_1",
"type": "function",
"function": {
"name": "cronjob",
"arguments": "{"action": "remove", "job_id": "2555d8919a51"}"
}
}
]
},
{
"role": "tool",
"content": "{\n "success": true,\n "message": "Cron job 'Merge PR 11326 when CI passes' removed.",\n "removed_job": {\n "id": "2555d8919a51",\n "name": "Merge PR 11326 when CI passes",\n "schedule": "once in 15m"\n }\n}",
"tool_call_id": "call_function_5mv5ncy4ch8g_1"
},
{
"role": "assistant",
"content": "",
"reasoning": "Now let me create a new one with an immediate first run.",
"finish_reason": "tool_calls",
"tool_calls": [
{
"id": "call_function_iis7oaj4k1ym_1",
"call_id": "call_function_iis7oaj4k1ym_1",
"response_item_id": "fc_function_iis7oaj4k1ym_1",
"type": "function",
"function": {
"name": "cronjob",
"arguments": "{"action": "create", "prompt": "Check the CI status of PR 11326 on repo using: gh pr view 11326 --repo repo --json state,mergeable,statusCheckRollup,mergeStateStatus\n\nLogic:\n1. If all status checks pass (no FAILURE/ERROR states) and mergeStateStatus is not BLOCKED/UNSTABLE/PENDING, merge it with: gh pr merge 11326 --repo repo --squash --delete-branch.\n2. If any status check FAILED or ERROR and NO checks are currently PENDING or IN_PROGRESS, post a SEPARATE comment for EACH failed job. For each failed job, run: gh pr comment 11326 --repo repo --body \"JOBNAME\" where JOBNAME is just the context string (e.g. \"premerge-linux-m2021\"). One job name per comment, nothing else.\n3. If CI is still running (some checks are PENDING/IN_PROGRESS), do nothing.\n4. If CI passed but mergeStateStatus is BLOCKED, report the merge conflict.", "schedule": "15m", "name": "Merge PR 11326 when CI passes", "repeat": 72, "deliver": "local"}"
}
}
]
},
{
"role": "tool",
"content": "{\n "success": true,\n "job_id": "bce029bf8cac",\n "name": "Merge PR 11326 when CI passes",\n "skill": null,\n "skills": [],\n "schedule": "once in 15m",\n "repeat": "72 times",\n "deliver": "local",\n "next_run_at": "2026-03-24T09:18:06.070281-04:00",\n "job": {\n "job_id": "bce029bf8cac",\n "name": "Merge PR 11326 when CI passes",\n "skill": null,\n "skills": [],\n "prompt_preview": "Check the CI status of PR 11326 on repo using: gh pr view 11326 --repo repo ...",\n "model": null,\n "provider": null,\n "base_url": null,\n "schedule": "once in 15m",\n "repeat": "72 times",\n "deliver": "local",\n "next_run_at": "2026-03-24T09:18:06.070281-04:00",\n "last_run_at": null,\n "last_status": null,\n "enabled": true,\n "state": "scheduled",\n "paused_at": null,\n "paused_reason": null\n },\n "message": "Cron job 'Merge PR 11326 when CI passes' created."\n}",
"tool_call_id": "call_function_iis7oaj4k1ym_1"
},
{
"role": "assistant",
"content": "Recreated. New job bce029bf8cac:\n\n- Next run: 09:18 EDT (~16 min from now)\n- Schedule: every 15 minutes, 72 repeats\n- Logic: same as before\n\nStill one check running: premerge-linux-m2021 (PENDING). All others passed.",
"reasoning": "Good, new job created with next_run_at of 2026-03-24T09:18:06. That's ~16 minutes from now (current time was 09:02:43). Let me report to the user.",
"finish_reason": "stop"
},
{

Steps to Reproduce

the chat history show the reproduce steps

Expected Behavior

It will show clear the cron job failed reason. And the last run at should be updated.

Actual Behavior

The last run at is not updated and no failed reason in the cron job information

Affected Component

CLI (interactive chat)

Messaging Platform (if gateway-related)

N/A (CLI only)

Operating System

Macos

Python Version

3.12

Hermes Version

commit 6302e56

Relevant Logs / Traceback

Root Cause Analysis (optional)

The last run at is not updated and no failed reason in the cron job information
I think the cron job run but no useful information was recorded and the last run at field is not updated

Proposed Fix (optional)

  1. the first fix would be updating the last run at field of the cron job.
  2. the second fix would be recorded a cron job as failed if it failed to run.

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

Metadata

Metadata

Assignees

No one assigned

    Labels

    type/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions