{"id":"76a54551e9fe894d","repo":"apache/kafka","slug":"github-token-is-not-set-in-the-environment","errorCode":null,"errorMessage":"GITHUB_TOKEN is not set in the environment","messagePattern":"GITHUB_TOKEN is not set in the environment","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"committer-tools/refresh_collaborators.py","lineNumber":58,"sourceCode":"logging.basicConfig(\n    format=\"%(asctime)s %(levelname)s %(message)s\",\n    level=logging.INFO,\n)\n\nGITHUB_TOKEN: str = os.getenv(\"GITHUB_TOKEN\")\nREPO_KAFKA_SITE: str = \"apache/kafka-site\"\nREPO_KAFKA: str = \"apache/kafka\"\nASF_YAML_PATH: str = \"../.asf.yaml\"\nTOP_N_CONTRIBUTORS: int = 10\n\n\ndef get_github_client() -> Github:\n    \"\"\"\n    Initialize GitHub client with token.\n    \"\"\"\n    if not GITHUB_TOKEN:\n        logging.error(\"GITHUB_TOKEN is not set in the environment\")\n        raise ValueError(\"GITHUB_TOKEN is not set in the environment\")\n\n    logging.info(\"Successfully initialized GitHub client\")\n    return Github(GITHUB_TOKEN)\n\n\ndef get_committers_list(repo: Repository) -> List[str]:\n    \"\"\"\n    Fetch the committers from the given repository.\n    \"\"\"\n    logging.info(f\"Fetching committers from the repository {REPO_KAFKA_SITE}\")\n    committers_file: ContentFile = repo.get_contents(\"committers.html\")\n    content: bytes = committers_file.decoded_content\n    soup: BeautifulSoup = BeautifulSoup(content, \"html.parser\")\n\n    committers = [login.text for login in soup.find_all(\"div\", class_=\"github_login\")]\n    logging.info(f\"Found {len(committers)} committers\")\n    return committers\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/committer-tools/refresh_collaborators.py#L40-L76","documentation":"Raised by refresh_collaborators.get_github_client() when the GITHUB_TOKEN environment variable is unset (falsy). The script uses PyGithub and authenticates every call with that token; without it, all repository/commit reads would 401. The check fails fast rather than attempting unauthenticated calls (which are rate-limited to near uselessness for this traversal).","triggerScenarios":"Running committer-tools/refresh_collaborators.py without exporting GITHUB_TOKEN, or exporting it in a different shell than the one running the script, or setting it to an empty string. The check happens inside get_github_client() at the very first step of main().","commonSituations":"New committer running the tool for the first time without reading the env-var requirement, running under cron/CI where the secret wasn't injected, terminal/shell that strips env vars (e.g. via sudo without -E), or token name typo (e.g. GH_TOKEN vs GITHUB_TOKEN).","solutions":["Export a personal access token: export GITHUB_TOKEN=$(gh auth token) or export GITHUB_TOKEN=ghp_xxx, then re-run.","If running under CI, add GITHUB_TOKEN to the job's environment/secret store.","Verify with: echo $GITHUB_TOKEN (should be non-empty) before running the script.","If you intended to use a differently named token, alias it: export GITHUB_TOKEN=$GH_TOKEN."],"exampleFix":"# before\n$ python committer-tools/refresh_collaborators.py\n# after\n$ export GITHUB_TOKEN=\"$(gh auth token)\"\n$ python committer-tools/refresh_collaborators.py","handlingStrategy":"validation","validationCode":"import os, sys\nGITHUB_TOKEN = os.getenv(\"GITHUB_TOKEN\")\nif not GITHUB_TOKEN:\n    sys.stderr.write(\"GITHUB_TOKEN is missing; export it first, e.g.\\n\"\n                     \"  export GITHUB_TOKEN=$(gh auth token)\\n\")\n    sys.exit(2)","typeGuard":"# Confirm the env var is present and non-empty (token value never logged).\ndef has_github_token() -> bool:\n    return bool(os.getenv(\"GITHUB_TOKEN\"))","tryCatchPattern":"from github import Github, GithubException\ntry:\n    client = get_github_client()\nexcept ValueError as e:\n    # Token missing: instruct the user / CI to provide it; do not proceed.\n    raise SystemExit(f\"Cannot run without a GitHub token: {e}\")","preventionTips":["Set GITHUB_TOKEN in your shell or CI secret store before running any committer-tools script.","Prefer 'gh auth token' to populate it from an existing GitHub CLI session instead of pasting a raw PAT.","Give the token only the minimum scopes needed (e.g. read:org, repo) and rotate it; never commit it to the repo.","Add a startup preflight check in wrapper scripts that fails fast with a clear message if the env var is unset."],"tags":["python","github","env-var","auth","committer-tools"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}