apache/kafka · error · ValueError

GITHUB_TOKEN is not set in the environment

Error message

GITHUB_TOKEN is not set in the environment

What it means

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

Source

Thrown at committer-tools/refresh_collaborators.py:58

logging.basicConfig(
    format="%(asctime)s %(levelname)s %(message)s",
    level=logging.INFO,
)

GITHUB_TOKEN: str = os.getenv("GITHUB_TOKEN")
REPO_KAFKA_SITE: str = "apache/kafka-site"
REPO_KAFKA: str = "apache/kafka"
ASF_YAML_PATH: str = "../.asf.yaml"
TOP_N_CONTRIBUTORS: int = 10


def get_github_client() -> Github:
    """
    Initialize GitHub client with token.
    """
    if not GITHUB_TOKEN:
        logging.error("GITHUB_TOKEN is not set in the environment")
        raise ValueError("GITHUB_TOKEN is not set in the environment")

    logging.info("Successfully initialized GitHub client")
    return Github(GITHUB_TOKEN)


def get_committers_list(repo: Repository) -> List[str]:
    """
    Fetch the committers from the given repository.
    """
    logging.info(f"Fetching committers from the repository {REPO_KAFKA_SITE}")
    committers_file: ContentFile = repo.get_contents("committers.html")
    content: bytes = committers_file.decoded_content
    soup: BeautifulSoup = BeautifulSoup(content, "html.parser")

    committers = [login.text for login in soup.find_all("div", class_="github_login")]
    logging.info(f"Found {len(committers)} committers")
    return committers

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Export a personal access token: export GITHUB_TOKEN=$(gh auth token) or export GITHUB_TOKEN=ghp_xxx, then re-run.
  2. If running under CI, add GITHUB_TOKEN to the job's environment/secret store.
  3. Verify with: echo $GITHUB_TOKEN (should be non-empty) before running the script.
  4. If you intended to use a differently named token, alias it: export GITHUB_TOKEN=$GH_TOKEN.

Example fix

# before
$ python committer-tools/refresh_collaborators.py
# after
$ export GITHUB_TOKEN="$(gh auth token)"
$ python committer-tools/refresh_collaborators.py
Defensive patterns

Strategy: validation

Validate before calling

import os, sys
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
if not GITHUB_TOKEN:
    sys.stderr.write("GITHUB_TOKEN is missing; export it first, e.g.\n"
                     "  export GITHUB_TOKEN=$(gh auth token)\n")
    sys.exit(2)

Type guard

# Confirm the env var is present and non-empty (token value never logged).
def has_github_token() -> bool:
    return bool(os.getenv("GITHUB_TOKEN"))

Try / catch

from github import Github, GithubException
try:
    client = get_github_client()
except ValueError as e:
    # Token missing: instruct the user / CI to provide it; do not proceed.
    raise SystemExit(f"Cannot run without a GitHub token: {e}")

Prevention

When it happens

Trigger: 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().

Common situations: 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).

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/76a54551e9fe894d.json. Report an issue: GitHub.