Skip to content

fix(cli): report the real reason gitt miner post rejects a PAT - #1655

Open
tryeverything24 wants to merge 1 commit into
entrius:testfrom
tryeverything24:fix/miner-post-pat-error-reason
Open

fix(cli): report the real reason gitt miner post rejects a PAT#1655
tryeverything24 wants to merge 1 commit into
entrius:testfrom
tryeverything24:fix/miner-post-pat-error-reason

Conversation

@tryeverything24

Copy link
Copy Markdown

PR body — tryeverything24 → entrius/gittensor

Branch: fix/miner-post-pat-error-reason (commit c663b3c, in WSL /root/gtn-pr)

Base: test

Title: fix(cli): report the real reason gitt miner post rejects a PAT

Summary

_validate_pat_locally() collapses three different failures into a bare None, so
miner_post always reports the same verdict — "GitHub PAT is invalid or expired" — even
when that's provably not the cause:

  1. PAT authenticates but lacks GraphQL access. /user returns 200, the GraphQL probe
    fails — the default outcome for GitHub's fine-grained PATs without the
    "Public Repositories (read-only)" permission (the token type GitHub now steers new users
    toward). The true cause was printed to stderr only, then the command still exited with
    the generic invalid-or-expired message. In --json mode the machine-readable envelope on
    stdout carried only the wrong cause, telling automation to rotate a token that works.
  2. Network failure reaching GitHub (requests.RequestException) was also reported as an
    invalid PAT — sending operators off to mint a new token when the fix is to retry.
  3. An actually invalid/expired token — the only case where the old message was right.

This is the same verdict-vs-transient distinction #1554 applied to issues submissions
(don't report a lookup failure as an empty result); this applies it to the PAT broadcast path.

Before / after (live capture, unreachable network)

# BEFORE — origin/test @ f70007c, GitHub unreachable:
$ gitt miner post --json --pat ghp_... 
{"success": false, "error": {"type": "cli_error", "message": "GitHub PAT is invalid or expired. Check your GITTENSOR_MINER_PAT."}}

# AFTER — same conditions:
$ gitt miner post --json --pat ghp_...
{"success": false, "error": {"type": "cli_error", "message": "Could not reach GitHub to validate the PAT (HTTPSConnectionPool(host='api.github.com', port=443): Max retries exceeded ...). Check your connection and retry."}}

Fix

_validate_pat_locally() now returns (login, reason):

  • /user non-200 (or no login in the response) → "invalid or expired" (unchanged wording)
  • GraphQL probe non-200 → the existing fine-grained-PAT permission message, now surfaced
    through _error() in both human and --json output instead of a stderr-only print
  • requests.RequestException → "Could not reach GitHub … retry", distinct from a bad token

miner_post passes the specific reason to _error(...). No behavior change on the success
path; the broadcast flow is untouched.

Tests

Updated the four existing mocked call sites for the new return shape, plus new
TestValidatePatLocally in tests/cli/test_miner_commands.py:

  • test_invalid_token_reports_invalid — 401 → invalid/expired
  • test_missing_graphql_access_reports_graphql_cause — 200 + GraphQL 403 → GraphQL message, NOT invalid/expired
  • test_network_failure_reports_connectivity_not_invalid — RequestException → connectivity message, NOT invalid/expired
  • test_valid_token_returns_login_and_no_error
  • test_post_json_mode_surfaces_specific_reason--json envelope carries the real cause
uv run pre-commit run --all-files                          # all hooks Passed
SKIP=pytest uv run pre-commit run --all-files --hook-stage pre-push   # pyright Passed, vulture Passed
uv run pytest tests/ -q                                    # 965 passed

_validate_pat_locally() collapses three different failures into a bare
None, so miner_post always reports "GitHub PAT is invalid or expired":

- A PAT that authenticates fine on /user but fails the GraphQL probe
  (the default for GitHub's fine-grained PATs without "Public
  Repositories (read-only)") printed the true cause to stderr only,
  then still exited with the generic invalid-or-expired verdict. In
  --json mode the machine-readable error on stdout carried only the
  wrong cause, telling automation to rotate a token that works.
- A network failure reaching GitHub (requests.RequestException) was
  also reported as an invalid PAT, sending operators off to mint a new
  token when the fix is to retry.

Return (login, reason) from _validate_pat_locally() and surface the
specific reason through _error() in both human and --json output. The
same verdict-vs-transient distinction was applied to issue submissions
in entrius#1554; this applies it to the PAT broadcast path.

Update the mocked call sites and add regression tests for the three
failure causes plus the --json envelope.
@xiao-xiao-mao xiao-xiao-mao Bot added the bug Something isn't working label Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant