Skip to content

fix(cron): skip Windows WSL launcher stub when resolving bash for .sh jobs - #60617

Closed
paulhopcraft-dot wants to merge 2 commits into
NousResearch:mainfrom
paulhopcraft-dot:claude/hermes-bug-fix-cd14dd
Closed

fix(cron): skip Windows WSL launcher stub when resolving bash for .sh jobs#60617
paulhopcraft-dot wants to merge 2 commits into
NousResearch:mainfrom
paulhopcraft-dot:claude/hermes-bug-fix-cd14dd

Conversation

@paulhopcraft-dot

Copy link
Copy Markdown

Summary

  • .sh/.bash cron scripts on Windows could resolve bash to the non-functional WSL launcher stub at %SystemRoot%\System32\bash.exe instead of a real Git Bash, because shutil.which("bash") returns whichever comes first on PATH. That stub exists on stock Windows even when no WSL distro is installed.
  • This bites background-service contexts specifically (the gateway's Windows Scheduled Task), since System32 typically precedes user-installed directories like Git's bin on PATH there. The resulting failure looked like: Script exited with code 1 ... Windows Subsystem for Linux has no installed distributions.
  • _resolve_bash() now walks PATH itself on Windows and skips both known non-functional stub directories (System32 and the WindowsApps app-execution alias), falling through to a real bash further down PATH. Non-Windows behavior (shutil.which / /bin/bash fallback) is unchanged.

Test plan

  • Added tests/tools/test_windows_native_support.py::TestCronSchedulerBashResolution cases: skips System32 stub, skips WindowsApps alias, returns None when only stubs are present, POSIX platforms unaffected.
  • pytest tests/cron/ tests/tools/test_windows_native_support.py — 421 passed; the 13 failures present are pre-existing on main too (POSIX-only assumptions: file permission bits, signal.SIGKILL, a Linux-only is_windows() test) — confirmed via baseline comparison, unrelated to this change.
  • Manually verified against the real filesystem on a native Windows box with PATH=System32;<git-bin> (the exact ordering that triggers the bug) — now resolves to the real Git Bash instead of the stub.
  • ruff check clean on both changed files.

🤖 Generated with Claude Code

paulhopcraft-dot and others added 2 commits June 9, 2026 17:52
…ire)

New MemoryProvider plugin so Hermes writes each turn to and reads context
from Paul's unified-memory service (http://localhost:18790, loopback,
unauthenticated hook+relevant endpoints — no bearer).

- sync_turn -> POST /api/memory/hooks/after-reply (background daemon thread,
  channel="hermes")
- prefetch -> GET /api/memory/relevant (bounded 2.5s, returns "" on any error)
- get_tool_schemas -> [] (context-only); 15 tests pass.
Activated via memory.provider: unified_memory in ~/.hermes/config.yaml.

KNOWN ISSUES found during live verify (tracked separately):
1. UM /search + /relevant return 0 (ctx.searchEngine null, fts5_active:false)
   -> read path delivers nothing until UM is fixed.
2. after-reply envelope nests sessionKey/channel under hookCtx, but UM's
   extractHookCtx reads them top-level -> writes bucket to "session-default"
   instead of channel="hermes". Same latent bug affects the CC hook.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… jobs

shutil.which("bash") can resolve to the non-functional WSL launcher at
%SystemRoot%\System32\bash.exe (present on stock Windows even without a
WSL distro installed) instead of a real Git Bash further down PATH.
Background-service contexts (the gateway's Scheduled Task) hit this
because System32 typically precedes user-installed dirs on PATH, so
.sh cron jobs failed with "Windows Subsystem for Linux has no
installed distributions" instead of running.

_resolve_bash() now walks PATH itself and skips both known stub dirs
(System32 and the WindowsApps app-execution alias), falling through to
a real bash further down PATH.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cron Cron scheduler and job management platform/windows Native Windows-specific behavior or breakage sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows labels Jul 8, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related to a saturated cluster of OPEN competing PRs fixing Windows cron .sh/.bash bash resolution: #52204 (broader consolidated fix — shared _find_bash() resolver used by cron + terminal tool + process registry, plus MSYS path.as_posix() backslash handling, supersedes #47920/#50191/#46364), #46364, #44350, and issues #46332/#23404.

This PR is the narrow cron-only variant: it adds _resolve_bash() in cron/scheduler.py that walks PATH and skips the System32 WSL launcher stub AND the WindowsApps app-execution alias, but does not include the MSYS backslash fix or the shared-resolver DRY consolidation. It is related_to, not a duplicate — a maintainer should pick between the narrow cron-scoped fix here and the broader consolidated #52204.

Note: this PR also bundles an unrelated new memory plugin (plugins/memory/unified_memory/__init__.py + test) that is out of scope for the cron fix and appears to be personal-fork branch contamination.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for isolating the Windows cron failure. The premise is still present on current main: cron/scheduler.py:2082 resolves bash through shutil.which("bash").

Problems

  • plugins/memory/unified_memory/__init__.py:216 registers a new in-tree memory provider. AGENTS.md:786-795 requires new memory backends to ship as standalone plugins, so this unrelated change must be removed from the PR.
  • The added cron-only resolver bypasses the established Windows precedence in tools/environments/local.py:524-557 and the documented contract at website/docs/user-guide/windows-native.md:108-116: configured HERMES_GIT_BASH_PATH, Hermes PortableGit, and known Git installs must win before PATH. It also leaves the same WSL-stub class in the shared resolver's PATH fallback at tools/environments/local.py:559-561.

Suggested changes

  • Split out the memory-provider work as a standalone plugin.
  • Put the WSL-launcher filtering into shared _find_bash() and route cron through it, with regression coverage for configured/PortableGit precedence.

Automated hermes-sweeper review.


def register(ctx) -> None:
"""Register unified-memory as a memory provider plugin."""
ctx.register_memory_provider(UnifiedMemoryProvider())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This registers a new provider under plugins/memory/, but AGENTS.md:786-795 closes the in-tree memory-provider set. Please remove this unrelated provider from the cron PR and publish it as a standalone plugin.

@andrexibiza

Copy link
Copy Markdown
Contributor

Reconciliation (2026-08-03): the WSL-launcher-stub skip this PR proposes is handled by the canonical #77532 (fix(cron): resolve bash for .sh jobs via shared Windows-aware resolver), which routes cron's bash resolution through the shared _find_bash() resolver (merged #47837) — Git Bash always preferred over the System32 WSL launcher when installed, with a clear actionable error when no usable bash exists. This branch is conflicting against main and its current head has no CI checks reported. The path half ships separately in #77393. Recommend closing as superseded by #77532 + #77393.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management P2 Medium — degraded but workaround exists platform/windows Native Windows-specific behavior or breakage sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants