NousResearch/hermes-agent · error · RuntimeError

PyYAML is required to write the iron-proxy config but is not

Error message

PyYAML is required to write the iron-proxy config but is not installed.

What it means

write_proxy_config() serializes the config dict to proxy.yaml with yaml.safe_dump and guards the import — if PyYAML isn't importable it raises rather than writing malformed output. In a normal Hermes install PyYAML is a core dependency, so hitting this means the environment is broken or the egress module is being vendored standalone without its deps.

Source

Thrown at agent/proxy_sources/iron_proxy.py:1368

            os.close(fd)
    except OSError as exc:
        raise RuntimeError(
            f"Refusing to start: could not pre-create audit log "
            f"{audit_path} with restrictive permissions ({exc}).  "
            f"Move or chmod any existing file at that path and retry."
        ) from exc


def write_proxy_config(config: Dict) -> Path:
    """Serialize the config dict to ``<hermes_home>/proxy/proxy.yaml``.

    Uses ``yaml.safe_dump`` so we never emit Python tags.
    """

    try:
        import yaml  # PyYAML is already a Hermes dep
    except ImportError as exc:
        raise RuntimeError(
            "PyYAML is required to write the iron-proxy config but is not "
            "installed."
        ) from exc

    state = _proxy_state_dir()
    out = state / "proxy.yaml"
    tmp_path = state / ".proxy.yaml.tmp"
    with open(tmp_path, "w", encoding="utf-8") as f:
        yaml.safe_dump(config, f, default_flow_style=False, sort_keys=False)
    # Tighten perms on the temp file BEFORE the atomic replace so the
    # final path is never briefly world-readable under a slack umask
    # (the config embeds proxy token values).  chmod-after-replace would
    # leave a TOCTOU window; the 0o700 state dir mitigates but same-uid
    # processes could still race.
    os.chmod(tmp_path, stat.S_IRUSR | stat.S_IWUSR)
    os.replace(tmp_path, out)
    return out

View on GitHub (pinned to c896c09c42)

Solutions

  1. Install PyYAML into the active environment: `pip install pyyaml` (or reinstall hermes-agent so its pinned deps resolve).
  2. Verify you're running the interpreter/venv you think: `python -c "import yaml; print(yaml.__version__)"`.
  3. If vendoring the module standalone, declare pyyaml in that project's dependencies.
Defensive patterns

Strategy: validation

Validate before calling

def pyyaml_available() -> bool:
    try:
        import yaml  # noqa: F401
        return True
    except ImportError:
        return False

Try / catch

try:
    write_proxy_config(cfg)
except RuntimeError as e:
    if "PyYAML is required" in str(e):
        raise SystemExit("Install dependencies: pip install pyyaml")

Prevention

When it happens

Trigger: write_proxy_config() (called from `hermes egress setup`) in a Python env where `import yaml` raises ImportError — stripped venvs, system-managed distro packaging that split PyYAML out, or the module copied into another project without the dependency.

Common situations: Running with a system python whose PyYAML package was removed by an upgrade; minimal containers where the hermes venv was recreated partially; vendoring iron_proxy.py standalone.

Related errors


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/836996d36fa4d7ec. Report an issue: GitHub.