github/spec-kit · error · ValueError
auth.json must be a JSON object, got {type(raw).__name__}
Error message
auth.json must be a JSON object, got {type(raw).__name__} What it means
When loading auth.json, the config parser json.loads()s the file and requires the top level to be a JSON object (dict). Any other JSON type — array, string, number, true/false, null — raises ValueError with the actual type name, because provider entries can only be looked up on a mapping.
Source
Thrown at src/specify_cli/authentication/config.py:118
try:
mode = config_path.stat().st_mode
if mode & (stat.S_IRGRP | stat.S_IROTH):
import warnings
warnings.warn(
f"{config_path} is readable by group/others. "
"Consider restricting with: chmod 600 "
f"{config_path}",
UserWarning,
stacklevel=2,
)
except OSError:
pass # stat failed — skip permission check
raw = json.loads(config_path.read_text(encoding="utf-8"))
if not isinstance(raw, dict):
raise ValueError(f"auth.json must be a JSON object, got {type(raw).__name__}")
providers_raw = raw.get("providers")
if not isinstance(providers_raw, list):
raise ValueError("auth.json must contain a 'providers' array")
entries: list[AuthConfigEntry] = []
for i, entry_raw in enumerate(providers_raw):
if not isinstance(entry_raw, dict):
raise ValueError(f"providers[{i}]: must be a JSON object")
hosts = entry_raw.get("hosts")
if not isinstance(hosts, list) or not hosts:
raise ValueError(f"providers[{i}]: 'hosts' must be a non-empty array")
if not all(isinstance(h, str) and h.strip() for h in hosts):
raise ValueError(f"providers[{i}]: each host must be a non-empty string")
# Normalize hosts: strip whitespace and lowercase
hosts = [h.strip().lower() for h in hosts]
# Reject dangerous wildcard forms (e.g. *github.com matches github.com.evil.com)View on GitHub (pinned to bf88c9f9a8)
Solutions
- Wrap the content in an object with a providers array: {"providers": [ ... ]}.
- Validate before running: jq 'type' auth.json should print "object".
- If a script generates the file, dump {"providers": entries}, not the list itself.
Example fix
// before (auth.json)
[ {"hosts": ["github.com"], "provider": "github", "auth": "bearer"} ]
// after
{ "providers": [ {"hosts": ["github.com"], "provider": "github", "auth": "bearer"} ] } Defensive patterns
Strategy: type-guard
Validate before calling
import json
from pathlib import Path
raw = json.loads(Path("auth.json").read_text(encoding="utf-8"))
if not isinstance(raw, dict):
raise SystemExit("auth.json must contain a top-level JSON object") Type guard
from typing import Any
def is_auth_config_object(raw: Any) -> bool:
"""True when the parsed auth.json top level is a JSON object."""
return isinstance(raw, dict) Try / catch
try:
entries = load_auth_config(path)
except ValueError as exc:
if "must be a JSON object" in str(exc):
raise SystemExit(f"restructure auth.json: {exc}") from exc
raise Prevention
- Keep auth.json shaped as {"providers": [...]} — never a bare array.
- Validate with jq 'type' == "object" after every edit.
- Generate the file from Python with json.dump({"providers": entries}, ...).
When it happens
Trigger: auth.json containing just [ {...} ] (a top-level array of providers), "...", 42, null, or a bare true; commonly a truncated edit or wrapping mistake where the outer {} braces were deleted.
Common situations: Hand-editing auth.json and accidentally removing the outer braces while moving a provider entry; generating the file with json.dump(providers_list) instead of json.dump({"providers": providers_list}); emptying the file to null while debugging.
Related errors
- providers[{i}]: each host must be a non-empty string
- auth.json must contain a 'providers' array
- providers[{i}]: must be a JSON object
- providers[{i}]: 'hosts' must be a non-empty array
- AzureDevOpsAuth does not support auth scheme {auth_scheme!r}
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/e5a29555fd6cf8f9.
Report an issue: GitHub.