NousResearch/hermes-agent · error
no install root
Error message
no install root
What it means
Terminal ValueError from the schedule parser in cron/jobs.py (parse_schedule): every supported format — 'every ...' interval, cron expression, ISO timestamp, and plain duration — failed to match. The message enumerates the four accepted forms, so the input matched none of them. Nothing is persisted; this is pure input validation.
Source
Thrown at apps/bootstrap-installer/src/store.ts:354
$route.set('progress')
await invoke('start_update')
}
export async function cancelInstall(): Promise<void> {
if (fakeMode()) {
fakeCancelled = true
return
}
await invoke('cancel_bootstrap')
}
export async function launchHermesDesktop(): Promise<void> {
if (fakeMode()) {throw new Error('Preview mode — launching is disabled.')}
const installRoot = $bootstrap.get().installRoot
if (!installRoot) {throw new Error('no install root')}
await invoke('launch_hermes_desktop', { installRoot })
}
export async function openLogDir(): Promise<void> {
if (fakeMode()) {return}
await invoke('open_log_dir')
}
// ---------------------------------------------------------------------------
// Dev-only isolated preview ("fake boot")
//
// Synthesises the manifest + stage/log events Rust normally streams, so the
// whole reskin can be reviewed in a plain browser (`npm run dev`):
// ?fake=install welcome → [ INSTALL ] → success
// ?fake=update auto-runs the granular update flow
// ?fake=failure install that fails partway
// Gated on import.meta.env.DEV → stripped from the shipped Tauri bundle.
// ---------------------------------------------------------------------------View on GitHub (pinned to c896c09c42)
Solutions
- Use one of the four documented forms: duration '30m'/'2h'/'1d', interval 'every 30m'/'every monday 9am', 5-field cron '0 9 * * *', or ISO timestamp '2026-02-03T14:00:00'.
- Check for stray whitespace/quotes around the string before submitting.
- Verify cron expressions have exactly 5 space-separated fields.
- If generating schedules from model output, pre-validate against the four patterns and re-ask on failure.
Example fix
# before create_job(prompt="digest", schedule="every day at 9") # after create_job(prompt="digest", schedule="every day 9am") # or "0 9 * * *"
Defensive patterns
Strategy: validation
Validate before calling
import re
from datetime import datetime
def looks_like_valid_schedule(s: str) -> bool:
s = s.strip()
if re.fullmatch(r"\d+[mhd]", s): return True # duration
if s.lower().startswith("every "): return True # interval
if len(s.split()) == 5 and re.fullmatch(r"[\d*/,-]+( [\d*/,-]+){4}", s): return True # cron
try:
datetime.fromisoformat(s); return True # timestamp
except ValueError:
return False Try / catch
try:
job = create_job(prompt=p, schedule=schedule)
except ValueError as e:
if "Invalid schedule" in str(e):
# show the four accepted formats to the caller/model and retry once
raise Prevention
- Normalize natural-language schedules ('every day at 9') into one of the four machine forms before submission.
- Validate cron expressions have exactly 5 fields and duration strings match \d+[mhd].
When it happens
Trigger: Calling create_job / update_job / `hermes cron add` with strings like 'tomorrow', 'every monday at nine', '30 min' (space inside duration), '9am daily', or an empty/garbage schedule. Also cron strings with the wrong field count fall through to here.
Common situations: Natural-language schedules from an LLM that were never normalized, duration strings with units the parser doesn't know ('1w', '30s' if unsupported), or a user assuming a 6-field cron expression is accepted.
Related errors
- Preview mode — launching is disabled.
- Remote gateway URL is not valid: ${error.message}
- Timed out connecting to Hermes backend after ${timeoutMs}ms
- Desktop installation ID is invalid.
- Unknown uninstall mode: ${mode}
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/0ea577420a254cdc.
Report an issue: GitHub.