NousResearch/hermes-agent · error · RuntimeError

Refusing to extract unsafe archive member {member!r}: it esc

Error message

Refusing to extract unsafe archive member {member!r}: it escapes the extraction directory

What it means

Error "Refusing to extract unsafe archive member {member!r}: it escapes the extraction directory" thrown in NousResearch/hermes-agent.

Source

Thrown at agent/secret_sources/bitwarden.py:350

    zf: zipfile.ZipFile, member: str, dest_dir: Path
) -> Path:
    """Extract a single archive member, refusing path traversal.

    ``ZipFile.extract`` will happily honour member names containing
    ``../`` or absolute paths, letting a malicious archive write outside
    ``dest_dir`` (a "zip-slip").  We resolve the would-be target and
    confirm it stays within ``dest_dir`` before extracting.
    """
    dest_root = os.path.realpath(dest_dir)
    target = os.path.realpath(os.path.join(dest_root, member))
    # ``commonpath`` raises ValueError for e.g. different drives on
    # Windows; treat that as an escape too.
    try:
        contained = os.path.commonpath([dest_root, target]) == dest_root
    except ValueError:
        contained = False
    if not contained or target == dest_root:
        raise RuntimeError(
            f"Refusing to extract unsafe archive member {member!r}: "
            f"it escapes the extraction directory"
        )
    zf.extract(member, dest_root)
    return Path(target)


# ---------------------------------------------------------------------------
# Secret fetch + apply
# ---------------------------------------------------------------------------


def _token_fingerprint(token: str) -> str:
    """SHA-256 prefix used as a cache key — never logged, never displayed."""
    return hashlib.sha256(token.encode("utf-8")).hexdigest()[:16]


def _b64e(raw: bytes) -> str:

View on GitHub (pinned to c896c09c42)

Solutions

  1. Do not extract the archive member that escapes the target directory; re-download from the official release.
  2. Treat the archive as untrusted and verify its origin before extracting.

When it happens

Trigger: Thrown at agent/secret_sources/bitwarden.py:350 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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