hermes - ✅(Solved) Fix [Bug]: google-workspace skill setup.py fails — hermes_constants import + missing Google API deps [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

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…
GitHub stats
NousResearch/hermes-agent#12722Fetched 2026-04-20 12:17:15
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Participants
Timeline (top)
referenced ×3cross-referenced ×1

Error Message

try: from hermes_constants import display_hermes_home, get_hermes_home except ModuleNotFoundError: HERMES_AGENT_ROOT = Path(file).resolve().parents[4] if HERMES_AGENT_ROOT.exists(): sys.path.insert(0, str(HERMES_AGENT_ROOT)) from hermes_constants import display_hermes_home, get_hermes_home

Root Cause

setup.py lines 31-37:

try:
    from hermes_constants import display_hermes_home, get_hermes_home
except ModuleNotFoundError:
    HERMES_AGENT_ROOT = Path(__file__).resolve().parents[4]
    if HERMES_AGENT_ROOT.exists():
        sys.path.insert(0, str(HERMES_AGENT_ROOT))
    from hermes_constants import display_hermes_home, get_hermes_home

The fallback re-raises the same ModuleNotFoundError. Compare with google_api.py line 34:

HERMES_HOME = Path(os.getenv("HERMES_HOME", Path.home() / ".hermes"))

Additionally, Google API dependencies (google-api-python-client, google-auth-oauthlib, google-auth-httplib2) are not included in the Hermes nix environment, and the nix env lacks pip/ensurepip to self-install them.

Fix Action

Fixed

PR fix notes

PR #12729: fix(skills): google-workspace setup.py fallback when hermes_constants unavailable

Description (problem / solution / changelog)

Problem

The three google-workspace skill scripts each resolve HERMES_HOME differently:

ScriptPatternIssue
setup.pyfrom hermes_constants import ...Crashes outside Hermes process (ModuleNotFoundError)
google_api.pyPath(os.getenv("HERMES_HOME", ...))No .strip(), no empty-string handling
gws_bridge.pyOwn local get_hermes_home()Duplicated function, same missing edge cases

hermes_constants is described as "import-safe with no dependencies" but it lives inside the Hermes Python package — unreachable from system Python, nix envs without PYTHONPATH, or CI runners.

Fix

Extract the shared logic into a single _hermes_home.py helper that lives alongside the scripts:

scripts/
├── _hermes_home.py   ← NEW: shared HERMES_HOME resolution
├── setup.py          ← imports from _hermes_home
├── google_api.py     ← imports from _hermes_home
└── gws_bridge.py     ← imports from _hermes_home

_hermes_home.py delegates to hermes_constants when available (preserving profile support, Docker detection, etc.) and falls back to os.getenv("HERMES_HOME") with .strip() + empty-as-unset handling — matching the exact semantics of hermes_constants.get_hermes_home().

Each consumer script adds its own directory to sys.path (standard pattern for standalone scripts) and imports get_hermes_home / display_hermes_home from the helper.

What changed

  • New: scripts/_hermes_home.py — try hermes_constants, fallback to env var
  • Changed: setup.py — replaced broken parents[4] import with _hermes_home import
  • Changed: google_api.py — replaced inline os.getenv with _hermes_home import
  • Changed: gws_bridge.py — removed local get_hermes_home(), imports from _hermes_home
  • Tests: 7 new tests for the fallback path (env var, default, empty, display shortening, profile paths, custom paths)

Testing

  • pytest tests/skills/test_google_oauth_setup.py tests/skills/test_google_workspace_api.py20/20 passed
  • Manual: verified setup.py --check works with system Python (no hermes_constants)
  • Manual: verified google_api.py gmail search works unchanged

Closes #12722

Changed files

  • skills/productivity/google-workspace/scripts/_hermes_home.py (added, +42/-0)
  • skills/productivity/google-workspace/scripts/google_api.py (modified, +8/-1)
  • skills/productivity/google-workspace/scripts/gws_bridge.py (modified, +5/-2)
  • skills/productivity/google-workspace/scripts/setup.py (modified, +6/-7)
  • tests/skills/test_google_oauth_setup.py (modified, +66/-0)

Code Example

# System python — fails (no hermes_constants)
python3 ~/.hermes/skills/productivity/google-workspace/scripts/setup.py --check

# Hermes nix python — fails (no Google API deps, no pip)
$HERMES_PYTHON ~/.hermes/skills/productivity/google-workspace/scripts/setup.py --check

---

try:
    from hermes_constants import display_hermes_home, get_hermes_home
except ModuleNotFoundError:
    HERMES_AGENT_ROOT = Path(__file__).resolve().parents[4]
    if HERMES_AGENT_ROOT.exists():
        sys.path.insert(0, str(HERMES_AGENT_ROOT))
    from hermes_constants import display_hermes_home, get_hermes_home

---

HERMES_HOME = Path(os.getenv("HERMES_HOME", Path.home() / ".hermes"))

---

try:
    from hermes_constants import display_hermes_home, get_hermes_home
    HERMES_HOME = get_hermes_home()
except (ModuleNotFoundError, Exception):
    HERMES_HOME = Path(os.getenv("HERMES_HOME", Path.home() / ".hermes"))
    def display_hermes_home():
        return "~/.hermes" if str(HERMES_HOME) == str(Path.home() / ".hermes") else str(HERMES_HOME)
RAW_BUFFERClick to expand / collapse

Bug Description

The google-workspace skill scripts (setup.py and google_api.py) cannot run with a standard python or python3 invocation:

  1. setup.py imports hermes_constants at module level, which is only available inside the Hermes nix/pip environment — not on the system Python. The fallback (Path(__file__).resolve().parents[4]) assumes a specific directory layout that does not match the installed skill path (~/.hermes/skills/productivity/google-workspace/scripts/).

  2. Neither script can install its own deps because the Hermes nix environment does not include pip or ensurepip. The _ensure_deps() auto-install in setup.py always fails with No module named pip.

  3. google_api.py does NOT depend on hermes_constants (it uses os.getenv("HERMES_HOME")), creating an inconsistency between the two scripts in the same skill.

Steps to Reproduce

# System python — fails (no hermes_constants)
python3 ~/.hermes/skills/productivity/google-workspace/scripts/setup.py --check

# Hermes nix python — fails (no Google API deps, no pip)
$HERMES_PYTHON ~/.hermes/skills/productivity/google-workspace/scripts/setup.py --check

Expected Behavior

setup.py should work the same way as google_api.py — using os.getenv("HERMES_HOME") as fallback when hermes_constants is unavailable, and the Google API deps should either be bundled in the Hermes environment or the skill should document the correct invocation.

Actual Behavior

setup.py crashes with ModuleNotFoundError: No module named 'hermes_constants' on any Python that is not the Hermes package environment with the correct PYTHONPATH.

Affected Component

  • Skills (skill loading, skill hub, skill guard)

Messaging Platform

N/A (CLI only)

Debug Report

N/A — this is a code-level issue visible by reading setup.py lines 31-37 vs google_api.py line 34.

Operating System

macOS (nix-managed Hermes installation)

Python Version

System: 3.9.6, Hermes env: 3.12.13

Hermes Version

0.9.0

Root Cause Analysis

setup.py lines 31-37:

try:
    from hermes_constants import display_hermes_home, get_hermes_home
except ModuleNotFoundError:
    HERMES_AGENT_ROOT = Path(__file__).resolve().parents[4]
    if HERMES_AGENT_ROOT.exists():
        sys.path.insert(0, str(HERMES_AGENT_ROOT))
    from hermes_constants import display_hermes_home, get_hermes_home

The fallback re-raises the same ModuleNotFoundError. Compare with google_api.py line 34:

HERMES_HOME = Path(os.getenv("HERMES_HOME", Path.home() / ".hermes"))

Additionally, Google API dependencies (google-api-python-client, google-auth-oauthlib, google-auth-httplib2) are not included in the Hermes nix environment, and the nix env lacks pip/ensurepip to self-install them.

Proposed Fix

  1. In setup.py, replace the hermes_constants import with a fallback matching google_api.py:
try:
    from hermes_constants import display_hermes_home, get_hermes_home
    HERMES_HOME = get_hermes_home()
except (ModuleNotFoundError, Exception):
    HERMES_HOME = Path(os.getenv("HERMES_HOME", Path.home() / ".hermes"))
    def display_hermes_home():
        return "~/.hermes" if str(HERMES_HOME) == str(Path.home() / ".hermes") else str(HERMES_HOME)
  1. Add google-api-python-client, google-auth-oauthlib, google-auth-httplib2 to the Hermes environment dependencies (nix or pip).
  • I'd like to fix this myself and submit a PR

extent analysis

TL;DR

The most likely fix involves modifying setup.py to use a consistent fallback for HERMES_HOME and adding Google API dependencies to the Hermes environment.

Guidance

  • Replace the hermes_constants import in setup.py with a fallback using os.getenv("HERMES_HOME") to ensure consistency with google_api.py.
  • Add google-api-python-client, google-auth-oauthlib, and google-auth-httplib2 to the Hermes environment dependencies to resolve the missing dependencies issue.
  • Verify that the modified setup.py works as expected by running it with the Hermes nix Python environment.
  • Consider documenting the correct invocation for the skill to ensure users are aware of the required dependencies and environment setup.

Example

The proposed fix for setup.py is provided in the issue description:

try:
    from hermes_constants import display_hermes_home, get_hermes_home
    HERMES_HOME = get_hermes_home()
except (ModuleNotFoundError, Exception):
    HERMES_HOME = Path(os.getenv("HERMES_HOME", Path.home() / ".hermes"))
    def display_hermes_home():
        return "~/.hermes" if str(HERMES_HOME) == str(Path.home() / ".hermes") else str(HERMES_HOME)

Notes

The fix assumes that the Hermes environment can be modified to include the required dependencies. If this is not possible, alternative solutions may be needed, such as using a different dependency management approach or modifying the skill to use a different API.

Recommendation

Apply the proposed workaround by modifying setup.py and adding the required dependencies to the Hermes environment, as this addresses the root cause of the issue and ensures consistency between the two scripts.

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