hermes - 💡(How to fix) Fix Gateway silently abandons populated platforms/pairing/ when empty pairing/ dir exists in HERMES_HOME

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…

gateway/pairing.py:47 resolves PAIRING_DIR via:

PAIRING_DIR = get_hermes_dir("platforms/pairing", "pairing")

get_hermes_dir(new_subpath, old_name) in hermes_constants.py:124 returns home / old_name whenever home / old_name exists, regardless of whether it contains any data. As a result, if an empty $HERMES_HOME/pairing/ directory is present, the gateway silently switches to the legacy path and abandons any populated $HERMES_HOME/platforms/pairing/telegram-approved.json (and the same for any other platform).

For deployments using pairing-mode auth, this means every previously-approved user is suddenly unrecognized and gets prompted to re-pair from scratch.

Root Cause

  1. Post-upgrade state:
    • pairing/ directory was created at gateway-startup time (mtime 21:49:23) — empty
    • First user message after restart hit _secure_write on pairing/_rate_limits.json and pairing/telegram-pending.json (mtime 21:51:09)
    • Resolver → pairing/ (legacy fallback wins because the dir now exists)
    • Approved file in platforms/pairing/telegram-approved.json is now invisible
    • User gets "I don't recognize you yet" + a pairing code

Fix Action

Fix / Workaround

  1. Workaround that fixed it without bouncing the gateway:
    cp $HERMES_HOME/platforms/pairing/telegram-approved.json \
       $HERMES_HOME/pairing/telegram-approved.json
    chmod 600 $HERMES_HOME/pairing/telegram-approved.json

Code Example

PAIRING_DIR = get_hermes_dir("platforms/pairing", "pairing")

---

cp $HERMES_HOME/platforms/pairing/telegram-approved.json \
      $HERMES_HOME/pairing/telegram-approved.json
   chmod 600 $HERMES_HOME/pairing/telegram-approved.json
RAW_BUFFERClick to expand / collapse

Summary

gateway/pairing.py:47 resolves PAIRING_DIR via:

PAIRING_DIR = get_hermes_dir("platforms/pairing", "pairing")

get_hermes_dir(new_subpath, old_name) in hermes_constants.py:124 returns home / old_name whenever home / old_name exists, regardless of whether it contains any data. As a result, if an empty $HERMES_HOME/pairing/ directory is present, the gateway silently switches to the legacy path and abandons any populated $HERMES_HOME/platforms/pairing/telegram-approved.json (and the same for any other platform).

For deployments using pairing-mode auth, this means every previously-approved user is suddenly unrecognized and gets prompted to re-pair from scratch.

Observed on this end

Hit during routine hermes update v0.13.0 → v0.14.0 today:

  1. Pre-upgrade state, in a custom HERMES_HOME:

    • platforms/pairing/telegram-approved.json contained 2 approved users (timestamps from Apr 9 and May 1)
    • pairing/ did not exist
    • Resolver → platforms/pairing/. Gateway worked correctly.
  2. hermes update runs cleanly. Gateway is reloaded by launchd.

  3. Post-upgrade state:

    • pairing/ directory was created at gateway-startup time (mtime 21:49:23) — empty
    • First user message after restart hit _secure_write on pairing/_rate_limits.json and pairing/telegram-pending.json (mtime 21:51:09)
    • Resolver → pairing/ (legacy fallback wins because the dir now exists)
    • Approved file in platforms/pairing/telegram-approved.json is now invisible
    • User gets "I don't recognize you yet" + a pairing code
  4. Workaround that fixed it without bouncing the gateway:

    cp $HERMES_HOME/platforms/pairing/telegram-approved.json \
       $HERMES_HOME/pairing/telegram-approved.json
    chmod 600 $HERMES_HOME/pairing/telegram-approved.json

Smoking gun

A ~/.hermes/pairing/ empty directory has existed on this machine since the very first install (Apr 2, never touched since), even though we never used pairing-mode auth in the default home. So some code path creates an empty pairing/ directory under HERMES_HOME at install or first-boot time. That dormant empty dir is what flips the resolver and orphans the populated platforms/pairing/ data.

I didn't track down the exact creator, but candidates worth checking:

  • Gateway startup / PairingStore.__init__() (line 87 calls PAIRING_DIR.mkdir, but only on whatever the resolver returned, so that alone shouldn't create pairing/)
  • Some upgrade/migration helper called by hermes update
  • An init script or scaffold step from the installer

Suggested fixes

Pick one or combine:

  1. Resolver should prefer the populated path. get_hermes_dir could check both paths and pick the one that actually has files; ties go to the new layout. This is a one-line behavior change.

  2. Don't pre-create empty pairing/. Whatever scaffolds ~/.hermes/pairing/ empty at install time should stop. Resolver already handles "neither exists" correctly (falls back to new_subpath).

  3. Active one-shot migration. If both paths exist and only one has data, move it to the preferred new path on next gateway boot and log a migration record.

Option 1 is the safest because it also fixes anyone who's already hit this footgun without requiring them to manually move files.

Environment

  • Hermes Agent v0.14.0 (2026.5.16), upgraded from v0.13.0 (2026.5.7)
  • macOS (Darwin 25.3.0), zsh
  • Pairing-mode auth (no allowlist), Telegram gateway, custom HERMES_HOME
  • Related (different but adjacent issue I filed earlier): #21526 — _invalidate_update_cache skips custom HERMES_HOME paths

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 Gateway silently abandons populated platforms/pairing/ when empty pairing/ dir exists in HERMES_HOME