agentleFS
iapiap/hermes-guide/skills/diagnosing-auth/SKILL.md

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

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
  1. Very specific:

    Test the failing operation (e.g., hermes skills tap add ...

    line 81
  2. Very specific:

    If using a token in .env, confirm it was removed/refreshed and no longer causes 401s.

    line 82
  3. Distinctive:

    After applying a fix, confirm auth is healthy:

    line 87

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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):

WhereCurrent messageSource
Skill name lookup failsNo skill named '<name>' found in any source.hermes_cli/skills_hub.py::_resolve_short_name
Identifier / inspect / tap resolution failsCould 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:

PrioritySourceMethod labelNotes
1get_secret("GITHUB_TOKEN") or get_secret("GH_TOKEN")patfed by the profile secret scope (the $HERMES_HOME/.env file, loaded at import); if set, later priorities are never consulted
2gh auth tokengh-clikeyring-stored, no expiry; GitHub's authenticated limit (5,000 req/hr per GitHub docs)
3GitHub App JWT + installation tokengithub-apponly when app credentials are configured
4unauthenticatedanonymousGitHub'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_limit with Authorization: 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 200 from /rate_limit proves the token is valid, not that it can see the repo being installed — fine-grained PATs scoped to other repos answer 404 on that repository's endpoint. Probe the repo itself (GET /repos/<owner>/<repo>) with the same header: 404 on 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 .env for active (uncommented) GITHUB_TOKEN / GH_TOKEN lines — a commented line is inert, an active one wins priority 1.

3. Pitfalls (symptom → cause → fix)

  1. … found in any source / Could not find … in any source on a public repo with gh logged in (historic phrasing: Could not fetch from any source) — a dead GITHUB_TOKEN in the profile .env costs a failed first attempt (priority 1 is tried first). Temporary: comment out or delete the .env line — installs skip the dead attempt entirely. Permanent: replace the token with a live one and record its expiry beside it, or drop .env tokens entirely and rely on gh auth login. Current upstream rejects the dead token on 401 and falls through (see the reject helper in tools/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.)
  2. hermes skills inspect / tap resolution fails with Could not find '<owner/repo/path>' in any source on a correctly-formed identifier, while the tap is listed and gh works — the same dead .env token, on a different surface: inspect/tap resolution hits the GitHub API too. On current upstream the 401 rejects the token and falls through to gh-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 .env token.
  3. Anonymous rate-limit 403s during installs — no token anywhere (method anonymous): 60 req/hr exhausts quickly with multi-file skills. → gh auth login once (method gh-cli, 5,000 req/hr).
  4. 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 of gh auth login. If you keep one, write its expiry date next to the line.
  5. gh token suddenly invalid — rotated or revoked server-side. → gh auth status shows it; gh auth login re-authenticates.
  6. 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 to diagnosing-skills (discovery/identifier) and re-read the install output for a scan verdict.

4. Localization workflow

  1. GitHubAuth().auth_method() → pat? A token exists — probe it (§2): 401 → pitfalls 1–2 (remember: authenticated=True proves nothing); 200 → the token is fine, look elsewhere.
  2. gh-cli and still failing? Not auth — check the identifier (pitfall 6) and the scanner verdict in the output.
  3. anonymous? → pitfall 3 (add auth for anything beyond a couple of installs).
  4. 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:

  1. Identify the auth method via GitHubAuth().auth_method() (note: is_authenticated() only confirms a token/credential is present — it does not prove validity).
  2. Validate the credential against the GitHub API per §2 (e.g., GET https://api.github.com/rate_limit with the active credential; 401 = invalid/revoked, 200 = token alive). If the fix targets a specific repo, probe GET /repos/<owner>/<repo> with that credential as well.
  3. Test the failing operation (e.g., hermes skills tap add ... or the install that failed) — it should succeed or fail for a different reason.
  4. If using a token in .env, confirm it was removed/refreshed and no longer causes 401s.
  5. 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 list

Pass: 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

SeverityWhatEvidence
HIGHDead GITHUB_TOKEN in .env fails the first attemptGitHubAuth().auth_method() returns pat; API probe with the .env token returns 401
MEDIUMOlder 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 dead GITHUB_TOKEN line
  • tools/skills_hub_github.py — _resolve_token priority 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.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.