hermes - 💡(How to fix) Fix [Bug]: nixosModule `documents` option installs files to wrong paths [1 pull requests]

Official PRs (…)
ON THIS PAGE

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…

Root Cause

File: nix/nixosModules.nix

  1. Line 821: Activation script hardcodes workingDirectory as install target for all documents, but hermes-agent reads SOUL.md from HERMES_HOME and USER.md/MEMORY.md from HERMES_HOME/memories/
  2. Lines 55-65: documentDerivation does not mkdir -p for subdirectory components of the key name, breaking nested attr keys like "memories/USER.md"

Fix Action

Fixed

Code Example

install -o ${cfg.user} -g ${cfg.group} -m 0640 ${documentDerivation}/${name} ${cfg.workingDirectory}/${name}

---

${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: _value: let
  target = if name == "SOUL.md" then "${cfg.stateDir}/.hermes/SOUL.md"
    else if lib.elem name ["USER.md" "MEMORY.md"] then "${cfg.stateDir}/.hermes/memories/${name}"
    else "${cfg.workingDirectory}/${name}";
in ''
  install -D -o ${cfg.user} -g ${cfg.group} -m 0640 ${documentDerivation}/${name} ${target}
'') cfg.documents)}

---

lib.mapAttrsToList (name: value: let
  dir = dirOf name;
in ''
  mkdir -p $out/${dir}
  ${if builtins.isPath value || lib.isStorePath value
    then "cp ${value} $out/${name}"
    else "cat > $out/${name} <<'HERMES_DOC_EOF'\n${value}\nHERMES_DOC_EOF"}
'')
RAW_BUFFERClick to expand / collapse

Bug Description

The documents option in nix/nixosModules.nix installs all files into workingDirectory (default /var/lib/hermes/workspace), but hermes-agent reads personality/memory files from $HERMES_HOME and $HERMES_HOME/memories/, not from the working directory. This means SOUL.md, USER.md, and MEMORY.md placed via the documents option are silently ignored.

Steps to Reproduce

  1. Configure services.hermes-agent.documents."SOUL.md" with some content in your NixOS config
  2. Deploy / rebuild
  3. Observe that the file appears at /var/lib/hermes/workspace/SOUL.md
  4. Start hermes gateway — the agent does NOT pick up the SOUL.md personality

Expected Behavior

  • SOUL.md should be installed to $HERMES_HOME/SOUL.md (i.e. ${cfg.stateDir}/.hermes/SOUL.md)
  • USER.md / MEMORY.md should be installed to $HERMES_HOME/memories/ (i.e. ${cfg.stateDir}/.hermes/memories/)
  • Project context files (AGENTS.md, .cursorrules, etc.) should remain in workingDirectory ✅ (already correct)

Actual Behavior

All documents entries are installed to workingDirectory:

install -o ${cfg.user} -g ${cfg.group} -m 0640 ${documentDerivation}/${name} ${cfg.workingDirectory}/${name}

With default paths:

  • SOUL.md/var/lib/hermes/workspace/SOUL.md ❌ (should be /var/lib/hermes/.hermes/SOUL.md)
  • USER.md/var/lib/hermes/workspace/USER.md ❌ (should be /var/lib/hermes/.hermes/memories/USER.md)

Where hermes-agent actually reads files

FileActual read pathCode
SOUL.mdget_hermes_home() / "SOUL.md"agent/prompt_builder.py::load_soul_md()
USER.mdget_memory_dir() / "USER.md"$HERMES_HOME/memories/USER.mdtools/memory_tool.py::MemoryStore.load_from_disk()
MEMORY.mdget_memory_dir() / "MEMORY.md"$HERMES_HOME/memories/MEMORY.mdtools/memory_tool.py::MemoryStore.load_from_disk()
AGENTS.mdcwd_path / "AGENTS.md"workingDirectoryagent/prompt_builder.py::_load_agents_md()
.cursorrulescwd_path / ".cursorrules"workingDirectoryagent/prompt_builder.py::_load_cursorrules()

Secondary issue: nested keys not supported

The documents attrset does not support nested paths like "memories/USER.md" as keys:

  1. documentDerivation only does mkdir -p $out, so $out/memories/ is never created → cp/cat fails at build time
  2. install command does not use -D flag, so parent directories are not created at activation time

Affected Component

  • Configuration (config.yaml, .env, hermes setup)
  • Setup / Installation

Debug Report

N/A — this is a NixOS module configuration issue, not a runtime bug. The code analysis is provided above.

Operating System

NixOS (any version using the flake nixosModule)

Hermes Version

main branch (755b74fc2)

Root Cause Analysis

File: nix/nixosModules.nix

  1. Line 821: Activation script hardcodes workingDirectory as install target for all documents, but hermes-agent reads SOUL.md from HERMES_HOME and USER.md/MEMORY.md from HERMES_HOME/memories/
  2. Lines 55-65: documentDerivation does not mkdir -p for subdirectory components of the key name, breaking nested attr keys like "memories/USER.md"

Proposed Fix

Route files to the correct target path based on filename:

${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: _value: let
  target = if name == "SOUL.md" then "${cfg.stateDir}/.hermes/SOUL.md"
    else if lib.elem name ["USER.md" "MEMORY.md"] then "${cfg.stateDir}/.hermes/memories/${name}"
    else "${cfg.workingDirectory}/${name}";
in ''
  install -D -o ${cfg.user} -g ${cfg.group} -m 0640 ${documentDerivation}/${name} ${target}
'') cfg.documents)}

And fix documentDerivation to handle nested keys:

lib.mapAttrsToList (name: value: let
  dir = dirOf name;
in ''
  mkdir -p $out/${dir}
  ${if builtins.isPath value || lib.isStorePath value
    then "cp ${value} $out/${name}"
    else "cat > $out/${name} <<'HERMES_DOC_EOF'\n${value}\nHERMES_DOC_EOF"}
'')

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

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