Skip to content

docs(hermes-webui): document skills canonical-location requirement - #90

Merged
cori merged 1 commit into
mainfrom
docs/hermes-webui-skills-canonical-location
Sep 22, 2026
Merged

cori merged 1 commit into
mainfrom
docs/hermes-webui-skills-canonical-location

Conversation

@cori

@cori cori commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Summary

Document the runtime-config requirement that HERMES_HOME_HOST_PATH/skills/ must be a real directory inside the bind mount, not a symlink to a path outside it. The WebUI's /api/skills enumerates skills by walking ~/.hermes/skills/ from inside the container; if that path is a symlink pointing outside the bind mount, the container can't resolve it and _skills_list_from_dir 500s with FileExistsError [Errno 17] from mkdir().

Why docs-only

  • No hermes-webui source change (per the user's standing rule: don't modify upstream source for runtime-config issues).
  • No docker-compose.json change — the existing volume mount is correct; the issue is the shape of the host path, not the bind spec.
  • Upstream webui is moving toward rejecting symlinked paths on write paths (open PRs #5414/#5415/#5416 in nesquena/hermes-webui). The deployment-shape constraint aligns with that direction.

What this PR changes

Adds a new ### Skills directory layout section to apps/hermes-webui/metadata/description.md covering:

  1. The canonical path resolution (get_hermes_home() / "skills" in both hermes-agent and hermes-webui).
  2. The two requirements that have caused real breakage (real directory at mount time, no symlinks across the mount boundary).
  3. The version-control pattern: initialize a git repo at ~/.hermes/ itself; the existing .gitignore already excludes caches, sessions, secrets, and runtime state.

Verification

bun test (per CLAUDE.md) passes 126/126. This change is metadata-only and doesn't touch docker-compose.json or config.json, so no schema validation impact.

Test plan

Deploy this app store update on a fresh Runtipi install with ~/.hermes/skills as either a real directory or a symlink to a path inside the bind mount — both should boot cleanly. A symlink to a path outside the bind mount will reproduce the original /api/skills 500 (documented as the constraint to avoid).

The WebUI's /api/skills 500s when HERMES_HOME_HOST_PATH/skills/ is a
symlink to a path outside the bind mount, because the symlink target
is unreachable from the container's filesystem. Upstream webui code
(in api/routes.py _skills_list_from_dir) treats the broken-symlink
case as 'create the directory' and crashes on mkdir with
FileExistsError because the symlink itself exists.

This is a deployment-shape constraint, not an upstream bug worth
filing — upstream is moving toward rejecting symlinked paths on write
(PRs #5414/#5415/#5416), so the runtime contract is: skills live at
~/.hermes/skills/ as a real directory. Users who want version control
initialize a git repo at ~/.hermes/ itself; the existing .gitignore
already excludes caches, sessions, secrets, and runtime state.

No source change to hermes-webui; runtime-config docs only.
@cori
cori merged commit e0ee8c6 into main Sep 22, 2026
4 checks passed
@cori
cori deleted the docs/hermes-webui-skills-canonical-location branch September 22, 2026 19:15
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.

1 participant