Conversation
teknium1
added a commit
that referenced
this pull request
Sep 2, 2026
GitHub answers anonymous fetches with HTTP 401 during outages (and for renamed/private repos). git then prompts `Username for 'https://github.com':` on the inherited terminal and `hermes update` sits there — users read it as Hermes demanding a GitHub login. Every network git call in the updater (fetch/pull/push, apply + --check + fork sync) now runs with GIT_TERMINAL_PROMPT=0 / stdin=DEVNULL, so the 401 fails fast into the fetch-failure classifier, which now reports it as a GitHub-side rejection (likely outage) rather than blaming the user's credentials. Credential helpers/askpass are left configured so private-fork origins still authenticate. Live repro: PTY-attached update --check against a 401 origin hung 15s+ on the prompt before; exits rc=1 in 0.2s with the diagnosis after. Same class as #73751 (@Frowtek, pre-main.py decomposition); passive banner half salvaged from #101421 (@RobbertC5).
Collaborator
|
Merged via #101557 (30b83ab) — your commit was cherry-picked as-is with authorship preserved, alongside the same fix for the |
melon-xf
added a commit
to melon-xf/hermes-agent
that referenced
this pull request
Sep 3, 2026
GitHub answers anonymous fetches with HTTP 401 during outages (and for renamed/private repos). git then prompts `Username for 'https://github.com':` on the inherited terminal and `hermes update` sits there — users read it as Hermes demanding a GitHub login. Every network git call in the updater (fetch/pull/push, apply + --check + fork sync) now runs with GIT_TERMINAL_PROMPT=0 / stdin=DEVNULL, so the 401 fails fast into the fetch-failure classifier, which now reports it as a GitHub-side rejection (likely outage) rather than blaming the user's credentials. Credential helpers/askpass are left configured so private-fork origins still authenticate. Live repro: PTY-attached update --check against a 401 origin hung 15s+ on the prompt before; exits rc=1 in 0.2s with the diagnosis after. Same class as NousResearch#73751 (@Frowtek, pre-main.py decomposition); passive banner half salvaged from NousResearch#101421 (@RobbertC5).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Passive update checks can invoke Git against a public HTTPS remote while inheriting the terminal. If a proxy or transient GitHub response requests authentication, Git asks for a GitHub username and blocks Hermes startup even though the repository is public.
This change applies the existing non-interactive Git contract to both passive network probes in
hermes_cli/banner.py:subprocess.DEVNULLGIT_TERMINAL_PROMPT=0andGCM_INTERACTIVE=Neverthroughnoninteractive_git_env()This is the passive-banner counterpart to merged PR #73709. PR #73751 covers explicit
hermes updateoperations instead. It overlaps the passive-probe portion of #64478, but deliberately excludes that PR's unrelated OAuth and update-count changes, which have unresolved review findings.Related Issue
No issue exists; reproduced directly on current
main.Type of Change
Changes Made
hermes_cli/banner.py: make the hard-coded upstreamls-remoteand local-checkout fetch non-interactive and unable to read terminal stdin.tests/hermes_cli/test_update_check.py: assert both passive call sites disable terminal and Git Credential Manager prompts.tests/hermes_cli/test_update_check.py: make the touched cache fixture's JSON encoding explicit for Windows compatibility.How to Test
scripts/run_tests.sh tests/hermes_cli/test_update_check.py.uvx ruff==0.15.10 check hermes_cli/banner.py tests/hermes_cli/test_update_check.py.python3 scripts/check-windows-footguns.pywith the two changed files staged.401;_upstream_main_sha()should returnNoneimmediately without prompting.Verified on Linux Mint 22.3 with Python 3.11.15:
Nonein 0.038 seconds without promptingFull canonical-suite validation was completed on the exact pushed head. The first run reported 81 failures across 20 files; a fresh canonical retry left 80 failures across 19 files. Running that exact 19-file set against an untouched detached
origin/mainworktree atafc3d9d34reproduced the same 80 failures in the same files. The one non-repeating failure (tests/gateway/test_turn_lease.py) passed on retry. This establishes the remaining failures as base/environment failures rather than regressions from this two-file PR. The focused update-check suite remains 7/7 passing.Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — N/A; behavior-only bug fixcli-config.yaml.exampleif I added/changed config keys — N/A; no config changesCONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/AScreenshots / Logs
Not applicable; this removes an invisible blocking credential prompt from a passive subprocess path.