Skip to content

fix(desktop): preserve HERMES_DASHBOARD_SESSION_TOKEN from parent process - #38931

Closed
1RB wants to merge 1 commit into
NousResearch:mainfrom
1RB:fix/preserve-dashboard-token
Closed

fix(desktop): preserve HERMES_DASHBOARD_SESSION_TOKEN from parent process#38931
1RB wants to merge 1 commit into
NousResearch:mainfrom
1RB:fix/preserve-dashboard-token

Conversation

@1RB

@1RB 1RB commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Context

The previous docs recommended pinning HERMES_DASHBOARD_SESSION_TOKEN in ~/.hermes/.env for remote mode. The current docs switched to username/password auth (HERMES_DASHBOARD_BASIC_AUTH_*). Users who set up remote mode under the old docs still have a stale pinned token in .env.

The bug (legacy migration edge case)

When those users run hermes desktop (local mode), the Desktop app generates a fresh random HERMES_DASHBOARD_SESSION_TOKEN per boot and injects it into the child backend. Then python-dotenv loads ~/.hermes/.env with override=True, clobbering the valid parent-injected token with the stale pinned one. Auth mismatch → 401 on every API call → Desktop can't start until the stale token is manually removed.

New users following current docs won't hit this because they won't have a pinned session token in .env.

Why #38586 does not fix this in practice

PR #38586 gates the fix on os.environ.get("HERMES_DASHBOARD_TUI") == "1", but the Desktop app never sets HERMES_DASHBOARD_TUI. I grepped the entire codebase (apps/desktop/, hermes_cli/, all TS/JS/CJS) — the variable only exists in #38586's own test (monkeypatched) and patch. In real usage the condition is always false, so the 401 boot loop still happens for users with a stale pinned token.

This fix (workaround)

This PR captures the parent-injected token unconditionally before any dotenv or external-secret loading, and restores it at the end. It works, but it's a workaround — the real fix should be a config migration that strips the stale HERMES_DASHBOARD_SESSION_TOKEN from .env during update, following the exact pattern used for ANTHROPIC_TOKEN (version 8 → 9 migration in hermes_cli/config.py).

Why this isn't the ideal fix:

  • .env with override=True is designed to win over stale shell exports. The deeper issue is that .env is being used for both user configuration AND legacy runtime session state.
  • The ideal fix: bump _config_version to 27 and add a migration block if current_ver < 27: that detects HERMES_DASHBOARD_SESSION_TOKEN in .env and removes it, since remote mode now uses username/password auth and local mode auto-generates tokens per boot. This follows the established migration pattern (ANTHROPIC_TOKEN cleanup in migrate_config).

Copilot review addressed

  • Single capture-before, single restore-after all loading (including _apply_external_secret_sources). No duplication, linear sequence.
  • Restore runs after external secret sources, ensuring the parent-injected token wins even if Bitwarden or other sources have a conflicting value.

Recommendation

Close this PR in favor of a proper config migration (version 27 → strip HERMES_DASHBOARD_SESSION_TOKEN from .env if present, with a console message explaining the auth model changed). The migration approach matches the existing ANTHROPIC_TOKEN cleanup pattern and removes the root cause without adding permanent complexity to env_loader.py.

Fixes #38575.

Copilot AI review requested due to automatic review settings June 4, 2026 10:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR prevents python-dotenv loads from overwriting a session token injected into the environment (avoiding a 401 “boot loop” when ~/.hermes/.env contains a stale token).

Changes:

  • Capture HERMES_DASHBOARD_SESSION_TOKEN before loading dotenv files.
  • Restore the token after loading the user and project .env files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread hermes_cli/env_loader.py Outdated
Comment thread hermes_cli/env_loader.py Outdated
Comment thread hermes_cli/env_loader.py Outdated
Comment thread hermes_cli/env_loader.py Outdated
@1RB 1RB closed this Jun 4, 2026
@1RB 1RB reopened this Jun 4, 2026
@1RB
1RB force-pushed the fix/preserve-dashboard-token branch 4 times, most recently from 2dc87bf to 3e28ca0 Compare June 4, 2026 14:31
…cess

The Desktop app generates a fresh random token per boot and injects it into
the child backend process. A stale pinned token in .env from previous
remote-mode use causes a 401 auth mismatch and infinite SIGTERM boot loop.

Capture the parent-injected token unconditionally before any dotenv loading
and restore it after all loading (including external secret sources) completes.
This is safe because:
- Desktop local mode: parent injects random token -> captured -> .env loads
  -> token restored -> handshake succeeds
- hermes dashboard CLI / remote mode: no parent injection -> None captured
  -> .env token applies normally

Fixes NousResearch#38575.
@1RB
1RB force-pushed the fix/preserve-dashboard-token branch from 3e28ca0 to b7ea277 Compare June 5, 2026 06:52
@1RB 1RB changed the title fix(cli): preserve HERMES_DASHBOARD_SESSION_TOKEN from parent process fix(desktop): preserve HERMES_DASHBOARD_SESSION_TOKEN from parent process Jun 5, 2026
@1RB

1RB commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

Closing in favor of a proper config migration (version 27 → strip legacy HERMES_DASHBOARD_SESSION_TOKEN from .env) which follows the existing ANTHROPIC_TOKEN cleanup pattern.

@1RB 1RB closed this Jun 5, 2026
@1RB

1RB commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #39652. The runtime preservation approach in this PR was a workaround; the root fix is a config migration that strips the stale HERMES_DASHBOARD_SESSION_TOKEN from .env during hermes update (config version 27). This removes the legacy entry entirely rather than fighting python-dotenv override on every boot. Also fixes #38575 and supersedes #38586.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Pinned HERMES_DASHBOARD_SESSION_TOKEN in .env breaks Desktop LOCAL mode into SIGTERM boot loop

2 participants