diagnosing-auth
Skill6 starsChanged 8 days agoMITView on GitHub
Diagnose hub-install failures that end in '… found in any source' / 'Could not find … in any source' on public repos with gh logged in (historic phrasing: 'Could not fetch from any source') — a dead or shadowing GITHUB_TOKEN in the profile .env, the gh-cli fallback, 401-vs-anonymous probes, and rate-limit verdicts.
- Reads credentials
In this repository32 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- diagnosing-backupSkill
- diagnosing-bot-modeSkill
- diagnosing-browserSkill
- diagnosing-cli-tuiSkill
- diagnosing-commandsSkill
- diagnosing-configSkill
- diagnosing-cronSkill
- diagnosing-desktopSkill
- diagnosing-gatewaySkill
- diagnosing-hooksSkill
- diagnosing-host-pressureSkill
- diagnosing-mcpSkill
- diagnosing-memoriesSkill
- diagnosing-memorySkill
- diagnosing-pathSkill
- diagnosing-pluginsSkill
- diagnosing-profilesSkill
- diagnosing-providersSkill
- diagnosing-runtimeSkill
- diagnosing-secretsSkill
- diagnosing-sessionsSkill
- diagnosing-skillsSkill
- diagnosing-storageSkill
- diagnosing-triageSkill
- diagnosing-updateSkill
- diagnosing-voiceSkill
- hermes-configuration-guideSkill
- hermes-post-updateSkill
- installing-hermesSkill
- plugin-authoringSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 81
Test the failing operation (e.g., hermes skills tap add ...
- Very specific: line 82
If using a token in .env, confirm it was removed/refreshed and no longer causes 401s.
- Distinctive: line 87
After applying a fix, confirm auth is healthy:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Diagnosing Hub Authentication
Goal: reduce any "… found in any source" / GitHub 401 / rate-limit failure on hermes skills install or hermes plugins install to one concrete fix — remove or refresh a token, or add one.
Which string you will actually see (verified 2026-09-14). Upstream now emits two messages, and neither is the historic Could not fetch from any source (that phrasing survives only in the closed issue #98725's title):
| Where | Current message | Source |
| Skill name lookup fails | No skill named '<name>' found in any source. | hermes_cli/skills_hub.py::_resolve_short_name |
| Identifier / inspect / tap resolution fails | Could not find '<identifier>' in any source. | hermes_cli/skills_hub.py:463 |
These strings are what the adapter prints when a lookup finds nothing — auth is the most common cause, but not the only one. Keep this skill's triage order (§4): probe auth first — resolve the method, then probe that token (a dead high-priority token degrades every source adapter to "not found" at once, so it is the cheapest thing to rule out; the signature is all sources failing, not one). Only when the probe answers 200 and installs still fail does the cause move to non-auth territory: the identifier's source scope, repository access restrictions, or a scanner verdict. Do not replace credentials blindly — and do not skip the probe to chase the identifier either.
1. How auth resolves (priority order)
GitHubAuth (tools/skills_hub_github.py — it moved out of tools/skills_hub.py; the CLI surface lives in hermes_cli/skills_hub.py) tries methods in priority order and stops at the first that yields a token:
| Priority | Source | Method label | Notes |
| 1 | get_secret("GITHUB_TOKEN") or get_secret("GH_TOKEN") | pat | fed by the profile secret scope (the $HERMES_HOME/.env file, loaded at import); if set, later priorities are never consulted |
| 2 | gh auth token | gh-cli | keyring-stored, no expiry; GitHub's authenticated limit (5,000 req/hr per GitHub docs) |
| 3 | GitHub App JWT + installation token | github-app | only when app credentials are configured |
| 4 | unauthenticated | anonymous | GitHub's anonymous limit (60 req/hr per GitHub docs), public repos only |
The load-bearing fact: a stale token at priority 1 is tried first, and its 401 costs a failed attempt. Current upstream rejects the dead token and falls through to gh-cli and anonymous (see the reject helper in tools/skills_hub_github.py, fixed via #98725, closed) — installs recover without intervention. On older checkouts the 401 was swallowed and every GitHub-backed source surfaced the same generic not-found message — No skill named '<name>' found in any source. or Could not find '<identifier>' in any source. — on public repos too, which is when removing the token is the fix. (On versions without the exit-code fix, the failed install also exits 0 — do not trust the exit code alone; read the output.)
Second load-bearing fact: GitHubAuth().is_authenticated() checks presence, not validity. A dead fine-grained PAT (github_pat_…) reports auth_method='pat' / authenticated=True while every API call returns 401 (verified live: the auth probe passed and _github_get returned 401 in the same process). Trust only the §2 API probe, never the is_authenticated() flag.
2. How to inspect
Auth-method probe — what Hermes actually resolves right now:
import sys; sys.path.insert(0, "/path/to/hermes-agent") from tools.skills_hub_github import GitHubAuth # NOT tools.skills_hub (moved) a = GitHubAuth() print(a.auth_method(), a.is_authenticated()) # e.g. "gh-cli True"- Is the env token itself alive?
GET https://api.github.com/rate_limitwithAuthorization: Bearer <token>— print only the status code, never the token. 401 = dead (remove or refresh it); 200 = alive; compare against the same request without the header (public repos answer 200 anonymous). - Alive is not authorized. A
200from/rate_limitproves the token is valid, not that it can see the repo being installed — fine-grained PATs scoped to other repos answer404on that repository's endpoint. Probe the repo itself (GET /repos/<owner>/<repo>) with the same header:404on a live token means no access for that token (scope or wrong identifier), not a dead token. gh auth status— account, scopes, and whether the gh token is still valid.- Scan the profile
.envfor active (uncommented)GITHUB_TOKEN/GH_TOKENlines — a commented line is inert, an active one wins priority 1.
3. Pitfalls (symptom → cause → fix)
… found in any source/Could not find … in any sourceon a public repo withghlogged in (historic phrasing:Could not fetch from any source) — a deadGITHUB_TOKENin the profile.envcosts a failed first attempt (priority 1 is tried first). Temporary: comment out or delete the.envline — installs skip the dead attempt entirely. Permanent: replace the token with a live one and record its expiry beside it, or drop.envtokens entirely and rely ongh auth login. Current upstream rejects the dead token on 401 and falls through (see therejecthelper intools/skills_hub_github.py, #98725 closed), so installs recover even with the token present; on older checkouts the 401 was swallowed and removing the token was the only fix. (Verified end-to-end; see NousResearch/hermes-agent#98725.)hermes skills inspect/ tap resolution fails withCould not find '<owner/repo/path>' in any sourceon a correctly-formed identifier, while the tap is listed andghworks — the same dead.envtoken, on a different surface: inspect/tap resolution hits the GitHub API too. On current upstream the 401 rejects the token and falls through togh-cli/anonymous, so this surface recovers on its own; on older checkouts the 401 degraded every source adapter to "not found" (verified:_github_get→ 401 inside the CLI; the same identifier resolved fine with the token removed). → Same fix as pitfall 1: remove or refresh the.envtoken.- Anonymous rate-limit 403s during installs — no token anywhere (method
anonymous): 60 req/hr exhausts quickly with multi-file skills. →gh auth loginonce (methodgh-cli, 5,000 req/hr). - Fine-grained PAT stopped working — they always carry an expiry (max 1 year) and can be revoked; a 401 gives no reason.
github_pat_…tokens are in the dead-token class of pitfalls 1–2. → Refresh it, or drop it in favor ofgh auth login. If you keep one, write its expiry date next to the line. ghtoken suddenly invalid — rotated or revoked server-side. →gh auth statusshows it;gh auth loginre-authenticates.- Auth is fine but the install still fails — the failure is not auth: wrong identifier form (
owner/repo/skills/<name>), or the scanner blocked it. → Route todiagnosing-skills(discovery/identifier) and re-read the install output for a scan verdict.
4. Localization workflow
GitHubAuth().auth_method()→pat? A token exists — probe it (§2): 401 → pitfalls 1–2 (remember:authenticated=Trueproves nothing); 200 → the token is fine, look elsewhere.gh-cliand still failing? Not auth — check the identifier (pitfall 6) and the scanner verdict in the output.anonymous? → pitfall 3 (add auth for anything beyond a couple of installs).- Apply the fix, re-run
GitHubAuth().auth_method()to confirm the method, then re-run the install.
When probing the .env token, use Hermes's own loader — agent.secret_scope.get_secret("GITHUB_TOKEN") under the Hermes venv — and send the result to the §2 API probe. Ad-hoc text scans of .env can false-clear a token (a wrong grep pattern reads "token present" as "token absent" and sends you chasing the wrong layer).
Automate it: the §1–§2 probes are cron-able — a monthly health check that reports the method and the env-token probe status catches a dying token before installs break.
Apply and verify
After applying fixes:
- Identify the auth method via
GitHubAuth().auth_method()(note:is_authenticated()only confirms a token/credential is present — it does not prove validity). - Validate the credential against the GitHub API per §2 (e.g.,
GET https://api.github.com/rate_limitwith the active credential;401= invalid/revoked,200= token alive). If the fix targets a specific repo, probeGET /repos/<owner>/<repo>with that credential as well. - Test the failing operation (e.g.,
hermes skills tap add ...or the install that failed) — it should succeed or fail for a different reason. - If using a token in
.env, confirm it was removed/refreshed and no longer causes 401s. - For rate limits, confirm method changed (anonymous → gh-cli/pat) gives expected behavior.
Verification
After applying a fix, confirm auth is healthy:
hermes auth status <provider>Pass: The specified provider shows authenticated with the expected auth method (pat, gh-cli, or github-app).
Fail: Provider shows unauthenticated — re-run hermes auth add <provider> or check the .env token.
hermes skills install <name>Pass: Skill installs without a No skill named … found in any source or Could not find … in any source error.
Fail: Same error recurs — run the GitHubAuth().auth_method() probe (§2) and confirm the active method; if pat, probe the token against GET https://api.github.com/rate_limit for a 401.
hermes skills tap listPass: The target registry appears in the list.
Fail: Registry is absent — run hermes skills tap add <repo> (e.g. hermes skills tap add iap/hermes-guide) and retry.
Report
This skill diagnoses hub-install authentication failures — dead or shadowing GITHUB_TOKEN, gh-cli fallback issues, 401-vs-anonymous probes, and rate-limit verdicts. When you run the diagnostic workflow, present findings in the standard format below.
Summary
Your hermes skills install fails with "No skill named 'foo' found in any source" because a dead GITHUB_TOKEN in your .env file is tried first and its 401 fails the attempt. On current upstream the token is then rejected and installs fall through to gh-cli/anonymous; on older checkouts the 401 was silently swallowed, shadowing your working gh CLI token across every GitHub-backed source.
Findings
| Severity | What | Evidence |
| HIGH | Dead GITHUB_TOKEN in .env fails the first attempt | GitHubAuth().auth_method() returns pat; API probe with the .env token returns 401 |
| MEDIUM | Older checkouts degrade all GitHub-backed sources to "not found" | Install output: No skill named 'foo' found in any source. (current upstream recovers via fall-through instead) |
Recommended Fix
Comment out or delete both the GITHUB_TOKEN and GH_TOKEN lines in $HERMES_HOME/.env, then re-run hermes skills install <name>. On older checkouts the gh-cli fallback (priority 2) takes over immediately; on current upstream the install already recovered via fall-through, so if it still fails after removing the token, the token was not the sole cause — look elsewhere (identifier form, scanner verdict).
References
$HERMES_HOME/.env— the deadGITHUB_TOKENlinetools/skills_hub_github.py—_resolve_tokenpriority order (pat → gh-cli → github-app → anonymous)hermes_cli/skills_hub.py::_resolve_short_name— the "found in any source" error string
Facts re-verified 2026-09-14 against upstream source at commit 46a0daee58abbc1b07f84f505a5ba90f1958295c: tools/skills_hub_github.py (_resolve_token, _try_pat, _try_gh_cli, is_authenticated), hermes_cli/skills_hub.py (error strings), agent/secret_scope.py; plus the issue tracker (#98725 open). Module paths and error strings changed since the previous revision — the mechanism did not. Re-checked 2026-10-12 against upstream main (53bc70c5): #98725 closed, dead tokens are rejected with fall-through (see the reject helper in tools/skills_hub_github.py); error strings re-anchored. Re-anchored 2026-10-17 against upstream d97007c32 (baseline re-pin): the string moved again with main — both name-lookup citations converted to the _resolve_short_name symbol form (the string lives in that function; line-cite drift twice in a month ended it). Re-verify before reuse.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

