{"record":{"id":"374f6153031aaf09","repo":"NousResearch/hermes-agent","slug":"timed-out-connecting-to-hermes-backend-after-tim","errorCode":null,"errorMessage":"Timed out connecting to Hermes backend after ${timeoutMs}ms","messagePattern":"Timed out connecting to Hermes backend after (.+?)ms","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/desktop/electron/dashboard-token.ts","lineNumber":23,"sourceCode":" * spawns the local dashboard, but the dashboard is the source of truth for the\n * token it actually serves to the renderer. If those drift, HTTP readiness\n * probes still pass while /api/ws rejects the renderer's token.\n */\n\nconst DEFAULT_TOKEN_FETCH_TIMEOUT_MS = 3_000\n\nasync function fetchPublicText(url, options: any = {}) {\n  const { protocol } = new URL(url)\n\n  if (protocol !== 'http:' && protocol !== 'https:') {\n    throw new Error(`Unsupported Hermes backend URL protocol: ${protocol}`)\n  }\n\n  const timeoutMs = options.timeoutMs ?? DEFAULT_TOKEN_FETCH_TIMEOUT_MS\n\n  const res = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) }).catch(error => {\n    if (error.name === 'TimeoutError') {\n      throw new Error(`Timed out connecting to Hermes backend after ${timeoutMs}ms`)\n    }\n\n    throw error\n  })\n\n  const text = await res.text()\n\n  if (!res.ok) {\n    throw new Error(`${res.status}: ${text || res.statusText}`)\n  }\n\n  return text\n}\n\nfunction extractInjectedDashboardToken(html) {\n  const match = /window\\.__HERMES_SESSION_TOKEN__\\s*=\\s*(\"(?:\\\\.|[^\"\\\\])*\")/.exec(String(html || ''))\n\n  if (!match) {","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/apps/desktop/electron/dashboard-token.ts#L5-L41","documentation":"ValueError from create_job (cron/jobs.py:1732): a one-shot ('once') schedule resolved, but compute_next_run() returned None — the requested run_at is more than ONESHOT_GRACE_SECONDS (120s) in the past, so the job would never fire and is rejected at creation instead of sitting dead in the store. A warning is logged alongside.","triggerScenarios":"create_job with an ISO timestamp like '2025-01-01T09:00' (already past), or a duration so small the time elapsed between parse and validation; also clock skew where the scheduler host's clock is ahead of the client's.","commonSituations":"User schedules 'today at 9am' after 9am; timestamps built from a stale clock; jobs created on a machine whose timezone/clock differs from the gateway host; DST confusion making a 'future' local time actually past.","solutions":["Pick a future timestamp, or use a relative duration ('30m', '2h') which is computed from now.","Check the clock and timezone on the host running the cron scheduler — the grace window is only 120s.","For recurring work, use cron/interval schedules instead of one-shot timestamps."],"exampleFix":"# before (at 15:00)\ncreate_job(prompt=\"report\", schedule=\"2026-08-14T09:00\")\n\n# after\ncreate_job(prompt=\"report\", schedule=\"2026-08-14T16:00\")  # or \"2h\"","handlingStrategy":"validation","validationCode":"from datetime import datetime, timedelta\nfrom cron.jobs import ONESHOT_GRACE_SECONDS\n\ndef schedulable_one_shot(when: datetime) -> bool:\n    return when > datetime.now(when.tzinfo) + timedelta(seconds=ONESHOT_GRACE_SECONDS - 10)\n\n# or skip absolute times entirely and use a duration string: \"45m\"","typeGuard":null,"tryCatchPattern":"try:\n    job = create_job(prompt=p, schedule=\"2026-08-14T09:00\")\nexcept ValueError as e:\n    if \"in the past\" in str(e):\n        job = create_job(prompt=p, schedule=\"1h\")  # retry relative to now\n        raise","preventionTips":["Prefer relative durations for one-shots created programmatically — they can't be born in the past.","Compare timestamps against the scheduler host's clock/timezone, especially across SSH/containers."],"tags":["cron","schedule","one-shot","clock","validation"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}