Skip to content

[Bug]: Docker/Unraid — HERMES_UID below 1000 (e.g. 99) silently ignored on current main; #32559 fix covered env propagation only, plus pairing/ excluded from chown #38070

Description

@medzin

Summary

Follow-up to #32559 (closed as completed via #32412). #32412 correctly fixed the s6-overlay env-propagation half of that bug — a valid HERMES_UID now remaps. But the original Unraid symptom (HERMES_UID=99) still reproduces on the current image because of a different root cause that #32412 never targeted: the validate_uid_gid floor requires id >= 1000, so Unraid's conventional 99/100 is rejected and the runtime falls back to UID 10000. A second, related defect (pairing/ excluded from ownership reconciliation) produces the user-visible telegram-approved.json permission error.

Environment

  • Image: nousresearch/hermes-agent:main (identical digest to :latest), sha256:bedaa680898269ec1686a085fec144c0b762aade7c7d30fde3ec8044bbdb8410, built 2026-06-03T06:51:08Z (i.e. post-fix(docker): propagate env through s6 to cont-init and main CMD #32412 — it includes the #!/command/with-contenv sh cont-init wrapper).
  • Command: gateway run
  • Reproduced in a clean container environment; originally hitting Unraid users (UID 99 / GID 100).

Bug 1 — HERMES_UID/HERMES_GID below 1000 are silently ignored

docker/stage2-hook.sh:42:

validate_uid_gid() {
    case "$1" in
        ''|*[!0-9]*) return 1 ;;
        *) [ "$1" -ge 1000 ] && [ "$1" -le 65534 ] ;;
    esac
}

Evidence on the same image / same boot path:

# Valid UID >= 1000 -> remap fires, confirming #32412 env propagation works:
docker run -d -e HERMES_UID=5000 -e HERMES_GID=5000 -v v1:/opt/data nousresearch/hermes-agent:main gateway run
docker exec <c> id hermes      # -> uid=5000(hermes) gid=5000(hermes)
#   log: "[stage2] Changing hermes UID to 5000"

# Unraid's 99 -> rejected by the >=1000 floor, falls back to 10000:
docker run -d -e HERMES_UID=99 -e HERMES_GID=100 -v v2:/opt/data nousresearch/hermes-agent:main gateway run
docker exec <c> id hermes      # -> uid=10000(hermes) gid=10000(hermes)
#   no "[stage2] Changing hermes UID" line is logged

This contradicts the uid=99(hermes) confirmation that #32559's close was based on — it does not reproduce on this digest. I suspect that run didn't actually hit the floor.

Impact: Unraid's standard appdata owner is nobody:users = 99:100. Since the runtime ends up as UID 10000 while appdata is owned by 99:100, writes into /opt/data fail — this is the gateway_state.json PermissionError tracked in #32559.

Ask: Is the < 1000 floor intentional? The PUID/PGID docs imply NAS conventions (incl. Unraid's 99/100) are supported, which isn't currently true. Either lower/remove the lower bound (low NAS UIDs like 99 are legitimate), or document that Unraid/NAS users must choose a UID >= 1000 and chown appdata to match.

Bug 2 — pairing/ excluded from ownership reconciliation

Even when the runtime is 10000, stage2-hook.sh reconciles /opt/data plus a fixed subdir list (cron sessions logs hooks memories skills skins plans workspace home profiles) and a few explicit files, but pairing/ is deliberately excluded (#19788, to avoid clobbering host-mounted files). So a pre-existing /opt/data/pairing owned by a different UID stays unwritable:

docker volume create v
docker run --rm --user 0 -v v:/d --entrypoint chown nousresearch/hermes-agent:main -R 99:100 /d  # simulate prior/host ownership
docker run -d --name c -e HERMES_UID=99 -e HERMES_GID=100 -v v:/opt/data nousresearch/hermes-agent:main gateway run
docker exec c stat -c '%u:%g %n' /opt/data /opt/data/pairing
#   -> 10000:10000 /opt/data        (reconciled)
#   -> 99:100      /opt/data/pairing (NOT reconciled)
docker exec -u 10000 c sh -c 'echo x > /opt/data/pairing/telegram-approved.json'
#   sh: cannot create /opt/data/pairing/telegram-approved.json: Permission denied

This reproduces the exact error Unraid users hit when running hermes setup to pair Telegram:
PermissionError: [Errno 13] Permission denied: '/opt/data/pairing/telegram-approved.json'
— reported on the Unraid Community Apps support thread for this template: https://forums.unraid.net/topic/199030-support-medzin-hermes-agent/ . (#10270 is the same root cause from the root-created-file direction.)

Ask: add pairing to the reconciled-subdir set, or chown it to the resolved runtime UID whenever the parent is reconciled.

Workaround for affected users (Unraid)

Set HERMES_UID/HERMES_GID to a value >= 1000 (the default 10000 works) and fix appdata ownership on the host:

chown -R 10000:10000 /mnt/cache/appdata/hermes-agent   # the 'pairing' subfolder especially

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existsarea/dockerDocker image, Compose, packagingbackend/dockerDocker container executiontype/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions