{"record":{"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":"exception","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/996fb4585aa1bcc8980b0e1b8d6b168b986cd979/committer-tools/refresh_collaborators.py#L40-L76","documentation":"committer-tools/refresh_collaborators.py reads GITHUB_TOKEN from the environment at import time (os.getenv). get_github_client refuses to construct a PyGithub client when the token is missing and raises ValueError, because every GitHub API call (listing committers, reading .asf.yaml, opening PRs) requires authentication with sufficient rate limit.","triggerScenarios":"Running `python3 committer-tools/refresh_collaborators.py` in a shell or CI job where GITHUB_TOKEN is not exported, or is exported as an empty string.","commonSituations":"New contributor running the tool without reading docs; CI runner missing the secret; token name typo (e.g. GH_TOKEN instead of GITHUB_TOKEN); running under a different user/shell where the export was not persisted.","solutions":["Export a classic PAT or fine-grained token: `export GITHUB_TOKEN=ghp_...` then re-run.","In CI, add GITHUB_TOKEN as a secret/env var on the job.","Put `export GITHUB_TOKEN=...` in the project's local .env (sourced before running) - never commit the token.","Verify the token has repo scope for apache/kafka and apache/kafka-site."],"exampleFix":"# before\n$ python3 committer-tools/refresh_collaborators.py\nERROR: GITHUB_TOKEN is not set in the environment -> ValueError\n\n# after\n$ export GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxx\n$ python3 committer-tools/refresh_collaborators.py","handlingStrategy":"validation","validationCode":"import os\nif not os.getenv(\"GITHUB_TOKEN\"):\n    raise SystemExit(\"Set GITHUB_TOKEN before running: export GITHUB_TOKEN=ghp_...\")","typeGuard":"null","tryCatchPattern":"try:\n    client = get_github_client()\nexcept ValueError as e:\n    print(f\"Auth error: {e}\", file=sys.stderr)\n    sys.exit(2)","preventionTips":["Check `echo $GITHUB_TOKEN` is non-empty before running the tool.","Add GITHUB_TOKEN as a CI secret.","Use a fine-grained PAT scoped to apache/kafka + apache/kafka-site."],"tags":["tooling","github","auth","release-tools","python"],"backgroundTag":null,"analyzedSha":"996fb4585aa1bcc8980b0e1b8d6b168b986cd979","analyzedAt":"2026-08-11T22:03:28.655Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}