Skip to content

fix(install): preserve pip entry point when re-running on symlinked install#22472

Closed
wesleysimplicio wants to merge 2 commits into
NousResearch:mainfrom
wesleysimplicio:fix/install-symlink-shim-stomp
Closed

fix(install): preserve pip entry point when re-running on symlinked install#22472
wesleysimplicio wants to merge 2 commits into
NousResearch:mainfrom
wesleysimplicio:fix/install-symlink-shim-stomp

Conversation

@wesleysimplicio

Copy link
Copy Markdown
Contributor

Summary

Re-running scripts/install.sh on a system installed under an older layout destroys the pip-generated venv/bin/hermes entry point and replaces it with a self-recursing bash shim, so hermes hangs on every invocation.

Cause

setup_path() writes the launcher with cat > "$command_link_dir/hermes". On a prior install $command_link_dir/hermes is a symlink pointing at venv/bin/hermes. The redirect follows the symlink and overwrites the pip entry point with the shim body. $HERMES_BIN then resolves to the same path — exec calls itself.

Fix

rm -f the destination before the heredoc so the shim is created as a regular file in $command_link_dir, leaving the venv entry point intact. No restructuring of setup_path() — smallest change that captures the diagnosis.

Changes

  • scripts/install.sh — added rm -f "$command_link_dir/hermes" before the cat > heredoc.
  • tests/test_install_sh_symlink_stomp.py — new file:
    • static guard that the rm precedes the heredoc (and follows the mkdir).
    • behavioural reproducer that pre-creates the symlinked legacy layout, drives the real shim-write block extracted from install.sh, and asserts venv/bin/hermes survives.

Test plan

  • ./scripts/run_tests.sh tests/test_install_sh_symlink_stomp.py -v — both tests pass with fix.
  • Stash-verify: git stash push scripts/install.sh → both tests fail (static guard misses rm; behavioural test sees pip body replaced by shim). git stash pop restores fix and tests pass again.
  • bash -n scripts/install.sh clean.

Closes #21513
Refs #21454

🤖 Generated with Claude Code

…nstall

Re-running scripts/install.sh on a system installed under an older layout
destroys the pip-generated venv/bin/hermes entry point and replaces it
with a self-recursing bash shim, so 'hermes' hangs on every invocation.

Cause: setup_path() writes the launcher with 'cat > "$command_link_dir/hermes"'.
On a prior install $command_link_dir/hermes is a symlink pointing at
venv/bin/hermes. The redirect follows the symlink and overwrites the pip
entry point with the shim body. $HERMES_BIN then resolves to the same
path, and exec calls itself.

Fix: 'rm -f' the destination before the heredoc so the shim is created as
a regular file in $command_link_dir, leaving the venv entry point intact.
No restructuring of setup_path() — smallest change that captures the
diagnosis.

Adds tests/test_install_sh_symlink_stomp.py with a static guard (rm
precedes the heredoc) and a behavioural reproducer that pre-creates the
symlinked layout, drives the real shim-write block extracted from
install.sh, and asserts venv/bin/hermes survives.

Closes NousResearch#21513
Refs NousResearch#21454
Copilot AI review requested due to automatic review settings May 9, 2026 10:03

Copilot AI 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.

Pull request overview

Fixes a regression in scripts/install.sh where re-running the installer on a legacy (symlink-based) install layout could overwrite the pip-generated venv/bin/hermes entry point with a self-recursing shim, causing hermes to hang.

Changes:

  • Remove any pre-existing $command_link_dir/hermes before writing the shim heredoc to avoid following legacy symlinks.
  • Add regression tests that (1) statically guard ordering (rm -f before heredoc) and (2) reproduce the symlink-stomp scenario and assert the venv entry point survives.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
scripts/install.sh Deletes an existing hermes path in the command link dir before writing the launcher shim, preventing symlink-follow overwrite of the venv entry point.
tests/test_install_sh_symlink_stomp.py Adds static + behavioral regression coverage for the legacy symlink overwrite / infinite loop shim scenario.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/install.sh
# Remove any prior entry first: on systems that installed an older layout
# ($command_link_dir/hermes was a symlink to venv/bin/hermes), `cat >`
# follows the symlink and overwrites the pip-generated entry point with
# the shim body, producing a self-execing wrapper that hangs on every
Comment on lines +70 to +74
#!/usr/bin/env bash
set -euo pipefail
command_link_dir={command_link_dir!s}
HERMES_BIN={venv_entry!s}
{block}
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard labels May 11, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Duplicate of #21513 — same fix (rm -f before heredoc in install.sh setup_path), same issue (#21454), same title. Both PRs are open.

@teknium1

Copy link
Copy Markdown
Contributor

Superseded by #25734, which merged @Tranquil-Flow's earlier #21513 with the same one-line rm -f fix. Three contributors independently converged on this exact fix — thanks for the careful diagnosis and tests, credited in the merged PR. Merge commit c75e1a0.

@teknium1 teknium1 closed this May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants