Description
gitt issues register is the owner-only command that writes a new issue bounty. Before writing, it calls validate_github_issue() to check with GitHub that the target issue actually exists, is an issue (not a PR), and is reachable.
The helper has three possible outcomes:
- Issue confirmed OK → returns a dict with the issue data.
- Issue definitely invalid (404, or it turns out to be a PR) → raises and the CLI aborts.
- Verification could not be completed (network error, 403, 500, 502, 503, etc.) → prints a yellow warning like
Warning: GitHub API returned 503 — skipping issue check and returns None.
The third case is the problem. In gittensor/cli/issue_commands/mutations.py:139, issue_register() calls the helper but does not use its return value:
validate_github_issue(owner, repo_name, issue_number)
No result = ..., no if result is None: abort. The warning prints, execution continues, and at mutations.py:210-220 the CLI submits register_issue on-chain. In interactive mode the user at least sees the yellow warning before a default-Yes confirm prompt, but with -y / --yes or in non-interactive environments (CI, scripts) the prompt is skipped and the write happens with nothing in between.
So any GitHub outage or 5xx / 403 response during a registration attempt is currently enough for the CLI to put a bounty on-chain for an issue that was never actually verified.
Steps to Reproduce
- Run
gitt issues register --repo <owner>/<repo> --issue <n> --bounty <amount> -y as the contract owner.
- Arrange for
validate_github_issue() to hit the verification-skipped path. In practice this means GitHub temporarily returns 5xx / 403, or the HTTP call raises requests.RequestException. Reproduced here by mocking helpers.requests.get to return a 503 response and by forcing a RequestException.
- Observe: the CLI prints the yellow "skipping issue check" warning, and then still calls
contract_instance.exec('register_issue', ...) at mutations.py:210. Exit code is 0.
Expected Behavior
The owner-only mutation path should fail closed when GitHub verification cannot be completed. If the CLI cannot confirm that:
- the repository exists,
- the target is an issue and not a PR,
- the issue state was actually fetched,
then it should not submit the on-chain transaction. Something like a plain message along the lines of "Could not verify issue #N in owner/repo on GitHub (status 503). Try again when GitHub is reachable." and a non-zero exit would be the expected behavior for a command that is about to spend real ALPHA.
Read-only commands that also use these helpers can keep the current warn-and-skip behavior; only the mutation path needs to be strict.
Actual Behavior
The CLI prints the warning, returns from the helper, proceeds through the confirmation prompt (or skips it with -y), and submits the register_issue transaction. An on-chain bounty entry is created whose GitHub target was never verified.
The validator side does not auto-clean entries like this:
gittensor/utils/github_api_tools.py:1099-1101 — check_github_issue_closed() returns None on any non-200 response, without distinguishing "issue does not exist" from "GitHub is flaky".
gittensor/validator/issue_competitions/forward.py:92-98 — when check_github_issue_closed() returns None, the validator just logs a warning and continues.
So an entry registered during a verification skip can sit on-chain indefinitely, logged each cycle but never resolved or cancelled, until the owner manually runs the cancel_issue admin command.
Environment
- OS: Linux 6.8.0-107-generic
- Python version: 3.12 (project requires
>=3.12)
Description
gitt issues registeris the owner-only command that writes a new issue bounty. Before writing, it callsvalidate_github_issue()to check with GitHub that the target issue actually exists, is an issue (not a PR), and is reachable.The helper has three possible outcomes:
Warning: GitHub API returned 503 — skipping issue checkand returnsNone.The third case is the problem. In
gittensor/cli/issue_commands/mutations.py:139,issue_register()calls the helper but does not use its return value:No
result = ..., noif result is None: abort. The warning prints, execution continues, and atmutations.py:210-220the CLI submitsregister_issueon-chain. In interactive mode the user at least sees the yellow warning before a default-Yes confirm prompt, but with-y/--yesor in non-interactive environments (CI, scripts) the prompt is skipped and the write happens with nothing in between.So any GitHub outage or 5xx / 403 response during a registration attempt is currently enough for the CLI to put a bounty on-chain for an issue that was never actually verified.
Steps to Reproduce
gitt issues register --repo <owner>/<repo> --issue <n> --bounty <amount> -yas the contract owner.validate_github_issue()to hit the verification-skipped path. In practice this means GitHub temporarily returns 5xx / 403, or the HTTP call raisesrequests.RequestException. Reproduced here by mockinghelpers.requests.getto return a 503 response and by forcing aRequestException.contract_instance.exec('register_issue', ...)atmutations.py:210. Exit code is 0.Expected Behavior
The owner-only mutation path should fail closed when GitHub verification cannot be completed. If the CLI cannot confirm that:
then it should not submit the on-chain transaction. Something like a plain message along the lines of "Could not verify issue #N in owner/repo on GitHub (status 503). Try again when GitHub is reachable." and a non-zero exit would be the expected behavior for a command that is about to spend real ALPHA.
Read-only commands that also use these helpers can keep the current warn-and-skip behavior; only the mutation path needs to be strict.
Actual Behavior
The CLI prints the warning, returns from the helper, proceeds through the confirmation prompt (or skips it with
-y), and submits theregister_issuetransaction. An on-chain bounty entry is created whose GitHub target was never verified.The validator side does not auto-clean entries like this:
gittensor/utils/github_api_tools.py:1099-1101—check_github_issue_closed()returnsNoneon any non-200 response, without distinguishing "issue does not exist" from "GitHub is flaky".gittensor/validator/issue_competitions/forward.py:92-98— whencheck_github_issue_closed()returnsNone, the validator just logs a warning andcontinues.So an entry registered during a verification skip can sit on-chain indefinitely, logged each cycle but never resolved or cancelled, until the owner manually runs the
cancel_issueadmin command.Environment
>=3.12)