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
- Use a bare environment variable name string, e.g. `token_env: GITHUB_TOKEN`
- Drop `${...}` interpolation syntax — just the name
- 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
- token_env takes a bare variable name — no ${...} interpolation
- Validate env names with a regex before writing the config
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
- providers[{i}]: invalid host pattern {h!r}. Only exact hostn
- providers[{i}]: 'provider' must be a non-empty string
- providers[{i}]: 'auth' must be a non-empty string
- providers[{i}]: 'token' must be a non-empty string
- providers[{i}]: unknown provider {provider!r}; registered: {
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/1580f1783a5530df.
Report an issue: GitHub.