hermes - 💡(How to fix) Fix Desktop installer ignores existing CLI ~/.hermes/ with sessions, creates fresh DB in LOCALAPPDATA

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…

Error Message

  1. Respect HERMES_HOME: If the user has ~/.hermes/ from a CLI install, the Desktop should detect it and at minimum warn that it's creating a separate data directory.

Root Cause

In apps/desktop/electron/main.cjs, resolveHermesHome() (line 192-204):

function resolveHermesHome() {
  if (process.env.HERMES_HOME) return path.resolve(process.env.HERMES_HOME)
  if (USER_DATA_OVERRIDE) return path.join(path.resolve(USER_DATA_OVERRIDE), 'hermes-home')
  if (IS_WINDOWS && process.env.LOCALAPPDATA) {
    const localappdata = path.join(process.env.LOCALAPPDATA, 'hermes')
    const legacy = path.join(app.getPath('home'), '.hermes')
    if (!directoryExists(localappdata) && directoryExists(legacy)) return legacy
    return localappdata
  }
  return path.join(app.getPath('home'), '.hermes')
}

The logic at line 200 has a race condition: the Desktop installer (hermes-setup.exe) creates LOCALAPPDATA\hermes before resolveHermesHome() ever runs. So when the Electron app starts, directoryExists(localappdata) is true, the legacy fallback never triggers, and the user's ~/.hermes/ with all their CLI sessions is silently ignored.

Fix Action

Workaround

Setting HERMES_HOME environment variable before launching Desktop forces it to use the CLI's directory. Combined with the profile system (active-profile.json), both platforms can coexist under one HERMES_HOME with isolated profiles.

Code Example

function resolveHermesHome() {
  if (process.env.HERMES_HOME) return path.resolve(process.env.HERMES_HOME)
  if (USER_DATA_OVERRIDE) return path.join(path.resolve(USER_DATA_OVERRIDE), 'hermes-home')
  if (IS_WINDOWS && process.env.LOCALAPPDATA) {
    const localappdata = path.join(process.env.LOCALAPPDATA, 'hermes')
    const legacy = path.join(app.getPath('home'), '.hermes')
    if (!directoryExists(localappdata) && directoryExists(legacy)) return legacy
    return localappdata
  }
  return path.join(app.getPath('home'), '.hermes')
}

---

if (IS_WINDOWS && process.env.LOCALAPPDATA) {
    const localappdata = path.join(process.env.LOCALAPPDATA, 'hermes')
    const legacy = path.join(app.getPath('home'), '.hermes')

    // If legacy has real data (state.db with sessions), prefer it
    // even if LOCALAPPDATA exists (installer may have created it).
    const legacyDb = path.join(legacy, 'state.db')
    const localappdataDb = path.join(localappdata, 'state.db')

    if (directoryExists(legacy) && fileExists(legacyDb)) {
        if (!fileExists(localappdataDb)) {
            return legacy  // Honor the user's existing CLI setup
        }
    }
    return localappdata
}
RAW_BUFFERClick to expand / collapse

Bug Description

When a user has an existing Hermes CLI installation at ~/.hermes/ (with sessions, config, skills, memories) and then installs the Desktop app, the Desktop silently ignores all existing CLI data and creates a brand new LOCALAPPDATA\hermes\ directory with a fresh state.db. The user loses access to all their historical sessions with no warning.

Environment

  • Windows 10
  • Hermes CLI installed via pip (Python) with data at C:\Users\<user>\.hermes\
  • Hermes Desktop installed via hermes-setup.exe
  • CLI had 248 sessions, 47,236 messages in ~/.hermes/state.db
  • Desktop created new LOCALAPPDATA\hermes\state.db with 0 sessions

Root Cause

In apps/desktop/electron/main.cjs, resolveHermesHome() (line 192-204):

function resolveHermesHome() {
  if (process.env.HERMES_HOME) return path.resolve(process.env.HERMES_HOME)
  if (USER_DATA_OVERRIDE) return path.join(path.resolve(USER_DATA_OVERRIDE), 'hermes-home')
  if (IS_WINDOWS && process.env.LOCALAPPDATA) {
    const localappdata = path.join(process.env.LOCALAPPDATA, 'hermes')
    const legacy = path.join(app.getPath('home'), '.hermes')
    if (!directoryExists(localappdata) && directoryExists(legacy)) return legacy
    return localappdata
  }
  return path.join(app.getPath('home'), '.hermes')
}

The logic at line 200 has a race condition: the Desktop installer (hermes-setup.exe) creates LOCALAPPDATA\hermes before resolveHermesHome() ever runs. So when the Electron app starts, directoryExists(localappdata) is true, the legacy fallback never triggers, and the user's ~/.hermes/ with all their CLI sessions is silently ignored.

Expected Behavior

One of:

  1. Detect existing CLI data: If ~/.hermes/state.db exists with sessions, offer the user a choice (migrate, link, or use separate profile).
  2. Respect HERMES_HOME: If the user has ~/.hermes/ from a CLI install, the Desktop should detect it and at minimum warn that it's creating a separate data directory.
  3. Don't create LOCALAPPDATA prematurely: The installer should not create the data directory before resolveHermesHome() has a chance to evaluate the legacy path.

Impact

  • Data loss perception: User opens Desktop and sees 0 sessions where they had hundreds.
  • No warning: Zero indication that existing data was found and ignored.
  • Affects CLI-first users: Anyone who starts with the CLI and later tries Desktop hits this.

Workaround

Setting HERMES_HOME environment variable before launching Desktop forces it to use the CLI's directory. Combined with the profile system (active-profile.json), both platforms can coexist under one HERMES_HOME with isolated profiles.

Proposed Fix

In resolveHermesHome(), before falling through to localappdata, check if legacy/state.db exists and has real data:

if (IS_WINDOWS && process.env.LOCALAPPDATA) {
    const localappdata = path.join(process.env.LOCALAPPDATA, 'hermes')
    const legacy = path.join(app.getPath('home'), '.hermes')

    // If legacy has real data (state.db with sessions), prefer it
    // even if LOCALAPPDATA exists (installer may have created it).
    const legacyDb = path.join(legacy, 'state.db')
    const localappdataDb = path.join(localappdata, 'state.db')

    if (directoryExists(legacy) && fileExists(legacyDb)) {
        if (!fileExists(localappdataDb)) {
            return legacy  // Honor the user's existing CLI setup
        }
    }
    return localappdata
}

This ensures CLI-first users don't silently lose access to their data when they install Desktop.

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