unslothai/unsloth · critical · ValueError

GitHub token is required. Set it in the recipe config or the

Error message

GitHub token is required. Set it in the recipe config or the GH_TOKEN / GITHUB_TOKEN env var.

What it means

Raised by the GitHub repo seed scraper's token resolution (_resolve_token) when no GitHub token can be found. Resolution order: explicit recipe-level token argument, then GH_TOKEN env var, then GITHUB_TOKEN env var; if all are absent a ValueError is raised telling the user exactly where to supply one. The GitHub API requires authentication for the GraphQL and rate-limited REST calls this scraper makes.

Source

Thrown at studio/backend/plugins/data-designer-github-repo-seed/src/data_designer_github_repo_seed/scraper.py:72


def _resolve_token(token: str) -> ResolvedToken:
    if token:
        return ResolvedToken(
            value = token,
            source = "explicit token argument (recipe-level field)",
        )
    if os.environ.get("GH_TOKEN"):
        return ResolvedToken(
            value = os.environ["GH_TOKEN"],
            source = "GH_TOKEN environment variable",
        )
    if os.environ.get("GITHUB_TOKEN"):
        return ResolvedToken(
            value = os.environ["GITHUB_TOKEN"],
            source = "GITHUB_TOKEN environment variable",
        )
    raise ValueError(
        "GitHub token is required. Set it in the recipe config or the GH_TOKEN / GITHUB_TOKEN env var."
    )


def _read_jsonl(path: Path, max_rows: int | None = None):
    if not path.exists():
        return
    with path.open(encoding = "utf-8") as f:
        for i, line in enumerate(f):
            if not line.strip():
                continue
            if max_rows is not None and i >= max_rows:
                return
            try:
                yield json.loads(line)
            except json.JSONDecodeError:
                continue

View on GitHub (pinned to 203007d190)

Solutions

  1. Export GH_TOKEN or GITHUB_TOKEN with a personal access token before running: export GH_TOKEN=ghp_...
  2. Or set the token field in the recipe config so it is passed as the explicit token argument.
  3. In CI/Docker, ensure the secret is actually injected into the environment (check with a masked env dump).

Example fix

# before
$ python -m data_designer_github_repo_seed ...  # no token anywhere

# after
$ export GH_TOKEN="ghp_xxxx"
$ python -m data_designer_github_repo_seed ...
Defensive patterns

Strategy: validation

Validate before calling

import os

def github_token_available(config: dict | None = None) -> bool:
    if config and config.get("token"):
        return True
    return bool(os.environ.get("GH_TOKEN") or os.environ.get("GITHUB_TOKEN"))

Try / catch

try:
    run_seed(recipe)
except ValueError as e:
    if "GitHub token is required" in str(e):
        sys.exit("Set GH_TOKEN or GITHUB_TOKEN, or add 'token:' to the recipe, then retry.")
    raise

Prevention

When it happens

Trigger: Running the data-designer-github-repo-seed scraper without a token field in the recipe config and with neither GH_TOKEN nor GITHUB_TOKEN exported in the environment (e.g. in a container or CI job that forgot the secret).

Common situations: Local run works (token in shell rc file) but the same job fails in Docker/CI where env vars are not passed; token set under a different variable name (GITHUB_ACCESS_TOKEN, GH_PAT); recipe YAML missing the token field.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/67a41a31bffc8cc8. Report an issue: GitHub.