github/spec-kit · error · ValueError
providers[{i}]: auth={auth!r} requires 'token' or 'token_env
Error message
providers[{i}]: auth={auth!r} requires 'token' or 'token_env' What it means
Raised for the `bearer` and `basic-pat` auth schemes when neither `token` nor `token_env` was supplied. Token-based schemes require exactly one credential source at validation time, so a completely token-less entry is rejected before it can fail at request time.
Source
Thrown at src/specify_cli/authentication/config.py:180
# 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"):
if not token and not token_env:
raise ValueError(
f"providers[{i}]: auth={auth!r} requires 'token' or 'token_env'"
)
elif auth == "azure-ad":
tenant_id = entry_raw.get("tenant_id")
client_id = entry_raw.get("client_id")
client_secret_env = entry_raw.get("client_secret_env")
if not all([tenant_id, client_id, client_secret_env]):
raise ValueError(
f"providers[{i}]: auth='azure-ad' requires "
"'tenant_id', 'client_id', and 'client_secret_env'"
)
for field_name, field_val in [
("tenant_id", tenant_id),
("client_id", client_id),
("client_secret_env", client_secret_env),
]:
if not isinstance(field_val, str) or not field_val.strip():
raise ValueError(View on GitHub (pinned to bf88c9f9a8)
Solutions
- Add `token_env: <ENV_VAR_NAME>` and export the variable in your shell/CI
- Or inline the credential with `token: "..."` if acceptable for your workflow
- Verify the key spelling — only `token` and `token_env` count
Example fix
# before - hosts: ["github.com"] provider: github auth: bearer # after - hosts: ["github.com"] provider: github auth: bearer token_env: GITHUB_TOKEN
Defensive patterns
Strategy: validation
Validate before calling
if entry["auth"] in ("bearer", "basic-pat") and not (entry.get("token") or entry.get("token_env")):
raise SystemExit(
f"auth={entry['auth']!r} needs token or token_env — "
"there is no default env-var fallback"
) Type guard
def has_credential(entry: dict) -> bool:
if entry.get("auth") in ("bearer", "basic-pat"):
return bool(entry.get("token") or entry.get("token_env"))
return True Try / catch
try:
load_auth_config(raw)
except ValueError as exc:
if "requires 'token' or 'token_env'" in str(exc):
# set token_env from the provider's usual env var name and retry
raise
raise Prevention
- Always pair token-based schemes with token_env — the loader never guesses an env var
- Fail fast in wrappers: check token/token_env presence before calling the CLI
When it happens
Trigger: An entry with `auth: bearer` (or `auth: basic-pat`) and both `token` and `token_env` absent/null.
Common situations: Expecting the library to fall back to a default env var like `GITHUB_TOKEN` automatically (it does not); deleting the token line to keep secrets out of the file without adding `token_env`; token key misspelled (`tokens`, `api_token`).
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}]: 'token_env' must be a non-empty string
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/644c5f1d4f7c585c.
Report an issue: GitHub.