hermes - ✅(Solved) Fix google-workspace setup.py crashes under macOS system python3 (auto-reexec into venv) [1 pull requests, 2 comments, 2 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#14688Fetched 2026-04-24 06:15:19
View on GitHub
Comments
2
Participants
2
Timeline
7
Reactions
0
Author
Timeline (top)
labeled ×4commented ×2cross-referenced ×1

Error Message

Traceback (most recent call last): File "scripts/setup.py", line 32, in <module> from hermes_constants import display_hermes_home, get_hermes_home File "/Users/.../.hermes/hermes-agent/hermes_constants.py", line 60, in <module> def get_optional_skills_dir(default: Path | None = None) -> Path: TypeError: unsupported operand type(s) for |: 'type' and 'NoneType' ModuleNotFoundError: No module named 'hermes_constants'

Root Cause

Root causes (two)

Fix Action

Fix / Workaround

With both patches, the command /usr/bin/python3 setup.py --check transparently reexecs into the venv python and returns AUTHENTICATED: Token valid at … instead of crashing.

PR fix notes

PR #14709: fix(google-workspace): bootstrap setup script under macOS system python

Description (problem / solution / changelog)

Why change

  • google-workspace setup checks can crash on macOS when agents invoke /usr/bin/python3 (3.9)
  • installed skill copies also fall back to the wrong import root when hermes_constants is not directly importable
  • this makes valid Google Workspace auth look broken and can trap agents in setup loops

Files changed

  • skills/productivity/google-workspace/scripts/setup.py
  • tests/skills/test_google_oauth_setup.py

What changed

  • auto-reexec into Hermes venv python when interpreter is older than Python 3.10
  • resolve installed-skill fallback imports via ~/.hermes/hermes-agent
  • add regression tests for both bootstrap paths

Verification run

  • source /home/caragon/.hermes/hermes-agent/venv/bin/activate && pytest tests/skills/test_google_oauth_setup.py -q
  • result: 9 passed

Risk level

  • Low
  • change only touches Google Workspace skill bootstrap path before auth setup logic
  • covered by focused regression tests

Closes #14688

Changed files

  • skills/productivity/google-workspace/scripts/setup.py (modified, +30/-1)
  • tests/skills/test_google_oauth_setup.py (modified, +48/-0)

Code Example

Traceback (most recent call last):
  File "scripts/setup.py", line 32, in <module>
    from hermes_constants import display_hermes_home, get_hermes_home
  File "/Users/.../.hermes/hermes-agent/hermes_constants.py", line 60, in <module>
    def get_optional_skills_dir(default: Path | None = None) -> Path:
TypeError: unsupported operand type(s) for |: 'type' and 'NoneType'
ModuleNotFoundError: No module named 'hermes_constants'

---

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

---

import os, sys
from pathlib import Path

if sys.version_info < (3, 10):
    venv_py = Path.home() / ".hermes" / "hermes-agent" / "venv" / "bin" / "python"
    if venv_py.exists() and sys.executable != str(venv_py):
        os.execv(str(venv_py), [str(venv_py), str(Path(__file__).resolve()), *sys.argv[1:]])
    print(
        f"ERROR: This script requires Python 3.10+ (running {sys.version.split()[0]}).\n"
        f"Hermes venv python not found at {venv_py} — install it or run with Python 3.10+.",
        file=sys.stderr,
    )
    sys.exit(2)

---

# Before
HERMES_AGENT_ROOT = Path(__file__).resolve().parents[4]

# After
HERMES_AGENT_ROOT = Path(__file__).resolve().parents[4] / "hermes-agent"

---

$ /usr/bin/python3 scripts/setup.py --check
AUTHENTICATED: Token valid at /Users/.../.hermes/google_token.json

$ ~/.hermes/hermes-agent/venv/bin/python3 scripts/setup.py --check
AUTHENTICATED: Token valid at /Users/.../.hermes/google_token.json
RAW_BUFFERClick to expand / collapse

google-workspace skill setup.py crashes cryptically under macOS system python3

Environment

  • Hermes: v2026.4.16-1165-gce089169 (cli __version__ = 0.10.0)
  • macOS (Apple Silicon), default system interpreter /usr/bin/python3 = 3.9.6
  • Agent: any local model that picks python3 from PATH for tool invocations (reproducible with Qwen3.5-35B-A3B-4bit + claude-sonnet classes)

Symptom

Agent is asked to do anything with Google Calendar / Gmail / Drive. Invokes the google-workspace skill. Agent decides to run python3 scripts/setup.py --check via the terminal tool to verify auth status. Gets:

Traceback (most recent call last):
  File "scripts/setup.py", line 32, in <module>
    from hermes_constants import display_hermes_home, get_hermes_home
  File "/Users/.../.hermes/hermes-agent/hermes_constants.py", line 60, in <module>
    def get_optional_skills_dir(default: Path | None = None) -> Path:
TypeError: unsupported operand type(s) for |: 'type' and 'NoneType'
ModuleNotFoundError: No module named 'hermes_constants'

Agent interprets this as "not authenticated" and either re-runs setup from scratch (infinite loop on retry) or gives up and tells user auth is broken. User's OAuth token is actually fine and valid on disk.

Root causes (two)

1. parents[4] fallback points at wrong directory

skills/productivity/google-workspace/scripts/setup.py: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

parents[4] resolves to ~/.hermes/ — but hermes_constants.py lives at ~/.hermes/hermes-agent/hermes_constants.py. The fallback adds the wrong path and the second import still fails. Need one more level down.

2. hermes_constants.py requires Python 3.10+ (PEP 604 unions), but macOS system python3 is 3.9

Even if path #1 is fixed, hermes_constants.py:60 uses Path | None = None syntax. Python 3.9 raises TypeError at import time, which falls outside except ModuleNotFoundError, so the fallback never runs.

macOS ships /usr/bin/python3 --version = 3.9.6 by default. Any agent tool-call of python3 setup.py … picks that up.

The skill's SKILL.md tells the agent to use $HERMES_HOME/hermes-agent/venv/bin/python — but agents don't always honor that, especially when they start fresh without priors or when model size causes it to simplify instructions.

Reproduction

  1. On macOS (Apple Silicon or Intel) with system /usr/bin/python3 = 3.9.x:
  2. Hermes installed at ~/.hermes/hermes-agent (default), google-workspace skill installed and fully authenticated (~/.hermes/google_token.json valid)
  3. Tell the agent: "create a calendar event for 8:30 AM" (or any Google Calendar / Gmail task)
  4. Observe the agent runs python3 scripts/setup.py --check and sees the Traceback above, then either retries or claims auth is broken

Proposed fix

Two changes to skills/productivity/google-workspace/scripts/setup.py:

(A) Auto-reexec into the Hermes venv python if we're on Python <3.10

Self-healing; caller doesn't need to know the venv path.

import os, sys
from pathlib import Path

if sys.version_info < (3, 10):
    venv_py = Path.home() / ".hermes" / "hermes-agent" / "venv" / "bin" / "python"
    if venv_py.exists() and sys.executable != str(venv_py):
        os.execv(str(venv_py), [str(venv_py), str(Path(__file__).resolve()), *sys.argv[1:]])
    print(
        f"ERROR: This script requires Python 3.10+ (running {sys.version.split()[0]}).\n"
        f"Hermes venv python not found at {venv_py} — install it or run with Python 3.10+.",
        file=sys.stderr,
    )
    sys.exit(2)

(B) Fix the parents[4] path for the case where hermes_constants isn't directly importable but Python is new enough

# Before
HERMES_AGENT_ROOT = Path(__file__).resolve().parents[4]

# After
HERMES_AGENT_ROOT = Path(__file__).resolve().parents[4] / "hermes-agent"

With both patches, the command /usr/bin/python3 setup.py --check transparently reexecs into the venv python and returns AUTHENTICATED: Token valid at … instead of crashing.

Impact

Every macOS user with a local-model-backed agent and a working Google Workspace OAuth token — the agent can't confirm auth status, so any subsequent Gmail/Calendar/Drive tool call loops or fails. The user-visible symptom is "Hermes got stuck on Google Workspace authentication" even though OAuth is fine.

Verified working with both interpreters locally after applying (A) + (B):

$ /usr/bin/python3 scripts/setup.py --check
AUTHENTICATED: Token valid at /Users/.../.hermes/google_token.json

$ ~/.hermes/hermes-agent/venv/bin/python3 scripts/setup.py --check
AUTHENTICATED: Token valid at /Users/.../.hermes/google_token.json

Broader suggestion (optional)

Other scripts under skills/*/scripts/ may have the same parents[N] fallback and the same Python-version vulnerability. A small helper module at skills/_common/bootstrap.py with a single ensure_hermes_venv() call would let all skill scripts self-heal identically.

extent analysis

TL;DR

The issue can be resolved by applying two patches to skills/productivity/google-workspace/scripts/setup.py: one to auto-reexec into the Hermes venv python if the system python version is less than 3.10, and another to fix the parents[4] path for importing hermes_constants.

Guidance

  • Apply the proposed fix (A) to auto-reexec into the Hermes venv python if the system python version is less than 3.10.
  • Apply the proposed fix (B) to fix the parents[4] path for importing hermes_constants.
  • Verify the fix by running /usr/bin/python3 setup.py --check and checking that it returns AUTHENTICATED: Token valid at … instead of crashing.
  • Consider applying the broader suggestion to create a helper module at skills/_common/bootstrap.py to let all skill scripts self-heal identically.

Example

The proposed fix (A) can be applied as follows:

if sys.version_info < (3, 10):
    venv_py = Path.home() / ".hermes" / "hermes-agent" / "venv" / "bin" / "python"
    if venv_py.exists() and sys.executable != str(venv_py):
        os.execv(str(venv_py), [str(venv_py), str(Path(__file__).resolve()), *sys.argv[1:]])

And the proposed fix (B) can be applied by changing the line:

HERMES_AGENT_ROOT = Path(__file__).resolve().parents[4]

to:

HERMES_AGENT_ROOT = Path(__file__).resolve().parents[4] / "hermes-agent"

Notes

The issue is specific to macOS users with a local-model-backed agent and a working Google Workspace OAuth token. The proposed fix assumes that the Hermes v

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