github/spec-kit · error · ValueError

providers[{i}]: 'token_env' must be a non-empty string

Error message

providers[{i}]: 'token_env' must be a non-empty string

What it means

Raised when `token_env` is present but is not a string or is whitespace-only. `token_env` names the environment variable holding the token (it is normalized via `_norm` later); it must be a bare environment-variable name as a non-empty string.

Source

Thrown at src/specify_cli/authentication/config.py:160

                    "(e.g. 'github.com' or '*.visualstudio.com')."
                )

        provider = entry_raw.get("provider", "")
        if not isinstance(provider, str) or not provider:
            raise ValueError(f"providers[{i}]: 'provider' must be a non-empty string")

        auth = entry_raw.get("auth", "")
        if not isinstance(auth, str) or not auth:
            raise ValueError(f"providers[{i}]: 'auth' must be a non-empty string")

        token = entry_raw.get("token")
        token_env = entry_raw.get("token_env")

        # Validate token/token_env types
        if token is not None and (not isinstance(token, str) or not token.strip()):
            raise ValueError(f"providers[{i}]: 'token' must be a non-empty string")
        if token_env is not None and (not isinstance(token_env, str) or not token_env.strip()):
            raise ValueError(f"providers[{i}]: 'token_env' must be a non-empty string")

        # Validate provider+scheme compatibility
        from . import get_provider as _get_provider
        _prov = _get_provider(provider)
        if _prov is None:
            from . import AUTH_REGISTRY
            raise ValueError(
                f"providers[{i}]: unknown provider {provider!r}; "
                f"registered: {sorted(AUTH_REGISTRY.keys())}"
            )
        if auth not in _prov.supported_auth_schemes:
            raise ValueError(
                f"providers[{i}]: provider {provider!r} does not support "
                f"auth scheme {auth!r}; supported: {list(_prov.supported_auth_schemes)}"
            )

        # Validate token source based on auth scheme
        if auth in ("bearer", "basic-pat"):

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Use a bare environment variable name string, e.g. `token_env: GITHUB_TOKEN`
  2. Drop `${...}` interpolation syntax — just the name
  3. Remove the key if you meant to inline the token with `token` instead

Example fix

# before
token_env: "${GITHUB_TOKEN}"
token_env: ["GITHUB_TOKEN"]

# after
token_env: GITHUB_TOKEN
Defensive patterns

Strategy: validation

Validate before calling

import re
_ENV_NAME = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
token_env = entry.get("token_env")
if token_env is not None and not _ENV_NAME.match(str(token_env)):
    raise SystemExit(f"token_env must be a bare env var name, got {token_env!r}")

Type guard

def is_env_name(value: object) -> bool:
    return isinstance(value, str) and bool(_ENV_NAME.match(value))

Try / catch

try:
    load_auth_config(raw)
except ValueError as exc:
    if "'token_env' must be a non-empty string" in str(exc):
        # replace ${VAR}/list forms with the bare variable name
        raise
    raise

Prevention

When it happens

Trigger: `"token_env": ""`, `"token_env": " "`, or a non-string value like `"token_env": true` / `"token_env": ["GITHUB_TOKEN"]`.

Common situations: Wrapping the env var name in a list or map because a template expected multiple values; an unset template placeholder leaving an empty string; copy-paste from a docker-compose-style `${VAR}` syntax instead of the bare name.

Related errors


AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14). Data as JSON: /api/errors/1580f1783a5530df. Report an issue: GitHub.