hermes - 💡(How to fix) Fix [Bug]: `no_agent=True` cronjob script execution ignores `terminal.backend`, always runs on scheduler host [2 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

  1. Check cronjob(action="list")last_status is "error". last_status: "error", with the message:

Additional Logs / Traceback (optional)

n/a — error is entirely deterministic and reproduced with a trivial id script. Option B (cheap guardrail): In _validate_cron_script_path(), add an exists() check against the scheduler's local filesystem and surface a clear error at creation time if the script can't be found. The error message should also mention that no_agent=True scripts always run on the scheduler host.

Root Cause

Root Cause Analysis (optional)

Fix Action

Fixed

Code Example

mkdir -p ~/.hermes/scripts
   echo -e '#!/bin/bash\nid' > ~/.hermes/scripts/id_check.sh
   chmod +x ~/.hermes/scripts/id_check.sh

---

cronjob(action="create", no_agent=True, script="id_check.sh", schedule="0 12 * * *")

---

Script not found: /home/debian/.hermes/scripts/id_check.sh

---

n/a — error is entirely deterministic and reproduced with a trivial `id` script.
RAW_BUFFERClick to expand / collapse

Bug Description

When terminal.backend is set to a remote backend (e.g. ssh), no_agent=True cronjobs with a script parameter still execute the script on the scheduler's local host instead of the remote backend. Scripts that were written to the remote host's filesystem via terminal() / write_file() fail with Script not found.

Additionally, cronjob create does not validate script existence at creation time, so invalid jobs are silently scheduled and fail only at runtime.

Steps to Reproduce

  1. Configure Hermes with terminal.backend: ssh pointing to a remote host.
  2. On the remote host, create a script via write_file or terminal:
    mkdir -p ~/.hermes/scripts
    echo -e '#!/bin/bash\nid' > ~/.hermes/scripts/id_check.sh
    chmod +x ~/.hermes/scripts/id_check.sh
  3. Create a cronjob via the agent tool with only the bare filename:
    cronjob(action="create", no_agent=True, script="id_check.sh", schedule="0 12 * * *")
  4. Trigger a run: cronjob(action="run", job_id="<id>").
  5. Check cronjob(action="list")last_status is "error".

Expected Behavior

The script executes on the configured remote terminal backend (oci-saulire via SSH) and reports the remote host's identity.

Actual Behavior

last_status: "error", with the message:

Script not found: /home/debian/.hermes/scripts/id_check.sh

The script exists on the remote host (confirmed via ls in a terminal() call), but the scheduler resolves the path against its own local HERMES_HOME and fails.

Affected Component

Tools (terminal, file ops, web, code execution, etc.)

Messaging Platform (if gateway-related)

No response

Debug Report

Report https://paste.rs/h1pfi agent.log https://paste.rs/CqRVm gateway.log https://paste.rs/dftv2

Operating System

Debian 13

Python Version

Python 3.13.5

Hermes Version

Hermes Agent v0.14.0 (2026.5.16)

Additional Logs / Traceback (optional)

n/a — error is entirely deterministic and reproduced with a trivial `id` script.

Root Cause Analysis (optional)

Traced the code path in cron/scheduler.py on main:

  1. _run_job_script() (lines 801–900) resolves the script path via _get_hermes_home() / "scripts" and executes it with subprocess.run().
  2. _get_hermes_home() resolves to the scheduler process's local ~/.hermes, not the remote backend's filesystem.
  3. There is no terminal backend passthroughsubprocess.run(argv, ...) runs locally regardless of terminal.backend.
  4. TERMINAL_CWD (set at line ~1392) only affects no_agent=False LLM tool calls; _run_job_script ignores it entirely.

Additionally, _validate_cron_script_path() in tools/cronjob_tools.py:255 only checks path-traversal containment. It never calls .exists(), so jobs are silently scheduled even when the script is absent from the scheduler host.

Proposed Fix (optional)

Option A (correct fix): Run script through the terminal backend. For remote backends, stream the script to the backend and execute it there, collecting stdout/stderr back to the scheduler. This makes no_agent=True scripts behave consistently with all other Hermes operations.

Option B (cheap guardrail): In _validate_cron_script_path(), add an exists() check against the scheduler's local filesystem and surface a clear error at creation time if the script can't be found. The error message should also mention that no_agent=True scripts always run on the scheduler host.

Option C (docs): Document that no_agent=True + script= always executes on the scheduler host, independent of terminal.backend, so SSH/Docker/modal/daytona users aren't surprised.

Are you willing to submit a PR for this?

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

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix [Bug]: `no_agent=True` cronjob script execution ignores `terminal.backend`, always runs on scheduler host [2 pull requests]