Skip to content

fix(cron): resolve jobs.json paths dynamically to honor HERMES_HOME changes#19375

Closed
kowenhaoai wants to merge 1 commit into
NousResearch:mainfrom
kowenhaoai:fix/cron-jobs-dynamic-paths
Closed

fix(cron): resolve jobs.json paths dynamically to honor HERMES_HOME changes#19375
kowenhaoai wants to merge 1 commit into
NousResearch:mainfrom
kowenhaoai:fix/cron-jobs-dynamic-paths

Conversation

@kowenhaoai

Copy link
Copy Markdown

Summary

cron/jobs.py snapshots the jobs-file, cron-dir, and output-dir paths into module-level constants at import time:

HERMES_DIR = get_hermes_home().resolve()
CRON_DIR = HERMES_DIR / "cron"
JOBS_FILE = CRON_DIR / "jobs.json"
OUTPUT_DIR = CRON_DIR / "output"

That pins all cron file I/O to whatever HERMES_HOME was active when the module first loaded, which breaks any downstream that legitimately switches HERMES_HOME at runtime — for example the Hermes WebUI's per-client profile cookie (nesquena/hermes-webui issue #798), or tests that swap in a temp home.

Change

  • Introduce get_cron_paths() that resolves the four paths dynamically from get_hermes_home() on every call.
  • Route every internal caller (load_jobs, save_jobs, ensure_dirs, etc.) through the helper instead of referencing the module constants directly.
  • Expose HERMES_DIR, CRON_DIR, JOBS_FILE, OUTPUT_DIR via a module-level __getattr__ fallback so existing from cron.jobs import JOBS_FILE imports keep working. Purely backwards-compatible.

Why keep the backwards-compat shim?

Several in-tree callers and third-party skills still import the old names directly. Removing them in one go would be invasive and unrelated to this fix, so __getattr__ forwards old names to the dynamic resolver without breaking anyone.

Test plan

  • pytest tests/cron/test_jobs.py -q → 64/64 pass
  • Manual: switch HERMES_HOME between two profiles at runtime, confirm list_jobs() returns the correct profile's jobs each time.
  • Manual: hermes cron list works unchanged.

Risk

Minimal. Paths resolve to the same location as before when HERMES_HOME is never modified, so single-profile users see no behavior change. Only consumers that actively switch HERMES_HOME at runtime gain the new correct behavior.

…hanges

cron/jobs.py snapshotted HERMES_DIR, CRON_DIR, JOBS_FILE, and OUTPUT_DIR
at import time, pinning all cron file I/O to whatever HERMES_HOME was
active when the module first loaded. That breaks downstream consumers
that legitimately switch profiles at runtime — for example the
hermes-webui per-client profile cookie feature (issue NousResearch#798) and tests
that monkey-patch the home dir via HERMES_HOME.

Replace the module-level constants with a dynamic get_cron_paths()
helper that reads get_hermes_home() on every call, and route every
internal reader (load_jobs, save_jobs, ensure_dirs, etc.) through it.

Keep the old names (HERMES_DIR, CRON_DIR, JOBS_FILE, OUTPUT_DIR) exposed
via module-level __getattr__ so existing imports of those attributes
continue to work unchanged — this is purely additive and backwards
compatible.

No behavior change for single-profile users: paths resolve to the same
location as before when HERMES_HOME is never modified. All existing
cron tests pass (64/64).
@kowenhaoai

Copy link
Copy Markdown
Author

Hi — polite maintainer ping on this one when you have a moment. 🙏

Context: this is one of two small PRs I'm submitting that I ran into while building a multi-profile WebUI workflow on top of hermes-agent. The companion PR is #19376 (image-gen model config); they're independent.

Happy to split this further, iterate on the backwards-compat strategy (I went with __getattr__ to avoid touching downstream callers), or add more coverage if you'd like. No rush — just flagging so it doesn't get lost in the queue.

Thanks for your time!

@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 May 3, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #4729 — same root cause: cron path constants frozen at import time before profile HERMES_HOME override applies.

1 similar comment
@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #4729 — same root cause: cron path constants frozen at import time before profile HERMES_HOME override applies.

@kowenhaoai

Copy link
Copy Markdown
Author

@alt-glitch thank you for the pointer — you're absolutely right, this is a duplicate of #4729. I missed it in my PR search (should have looked more broadly than the cron-tagged list). Apologies for the noise.

Closing this one in favor of #4729. I'll leave a small technical note on that PR in case any of the minor differences (backwards-compat __getattr__ shim for external imports of JOBS_FILE/HERMES_DIR) are useful to them.

My companion PR #19376 (image-gen model config) is unrelated to this area, so it remains open.

Thanks again for catching this!

@kowenhaoai

Copy link
Copy Markdown
Author

Closing as duplicate of #4729. See my comment above.

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 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.

3 participants