datawhalechina/hello-agents · error · MovieServiceError
TMDB 鉴权失败:请检查 Access Token / API Key
Error message
TMDB 鉴权失败:请检查 Access Token / API Key
What it means
MovieServiceError with status_code=401 raised when TMDB responds HTTP 401 to an authenticated request. This means credentials were present (they passed the _auth_headers_and_params guard) but are wrong or malformed: an expired/revoked v4 access token, a v3 api_key that is invalid, or an API-key-only key being sent where a Bearer token is required (TMDB v3 endpoints accept api_key query param, but a malformed token string yields 401).
Source
Thrown at Co-creation-projects/aatanxiao12-beep-YingQian/backend/app/services/movie_service.py:123
def _get(self, path: str, extra_params: Optional[Dict[str, Any]] = None) -> dict:
"""对 TMDB 发 GET,统一处理超时、网络错误与非 2xx / 非 JSON。"""
headers, params = self._auth_headers_and_params()
if extra_params:
for k, v in extra_params.items():
if v is not None and v != "":
params[k] = v
url = f"{TMDB_API_BASE}{path}"
try:
resp = self._client.get(url, headers=headers, params=params)
except httpx.TimeoutException as e:
raise MovieServiceError(f"TMDB 请求超时: {e}") from e
except httpx.HTTPError as e:
raise MovieServiceError(f"TMDB 网络错误: {e}") from e
if resp.status_code == 401:
raise MovieServiceError(
"TMDB 鉴权失败:请检查 Access Token / API Key",
status_code=401,
)
if resp.status_code == 404:
raise MovieServiceError("影片不存在或已下架", status_code=404)
if resp.status_code >= 400:
raise MovieServiceError(
f"TMDB 请求失败: HTTP {resp.status_code}, {resp.text[:200]}"
)
try:
return resp.json()
except ValueError as e:
raise MovieServiceError("TMDB 返回非 JSON") from e
def _poster_url(self, poster_path: Optional[str]) -> Optional[str]:
"""把 TMDB 相对 poster_path 拼成可访问的完整图片 URL。"""
if not poster_path:View on GitHub (pinned to 606a07d341)
Solutions
- Regenerate the API key / access token in TMDB account settings and update .env, then restart the service
- Strip whitespace/quotes from the value in .env (pydantic-settings keeps them verbatim)
- Verify the credential directly: curl -H 'Authorization: Bearer $TMDB_ACCESS_TOKEN' https://api.themoviedb.org/3/account — 200 means the token is good
- Ensure v4 token (JWT starting with eyJ) goes in TMDB_ACCESS_TOKEN and the 32-char v3 key goes in TMDB_API_KEY — do not swap them
Example fix
# before (mixed-up credentials in .env)
# TMDB_ACCESS_TOKEN=7a3f...v3_style_32_char_key
# after
# .env — v4 bearer token (JWT) in ACCESS_TOKEN, v3 key in API_KEY
TMDB_ACCESS_TOKEN=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOi...\
TMDB_API_KEY=7a3f9c...(unused if token present)
# sanity check before deploying:
# curl -s -o /dev/null -w '%{http_code}' \
# -H "Authorization: Bearer $TMDB_ACCESS_TOKEN" \
# https://api.themoviedb.org/3/account # expect 200 Defensive patterns
Strategy: try-catch
Validate before calling
# cheap local sanity: v4 tokens are long JWTs
from app.config import get_settings
def tmdb_token_plausible() -> bool:
token, key = get_settings().resolve_tmdb_credentials()
if token:
return token.startswith('eyJ') and len(token) > 100
return bool(key) and len(key) == 32 Try / catch
except MovieServiceError as e:
if e.status_code == 401:
page_env_setup_notice('TMDB credentials rejected — regenerate token')
return degrade()
raise Prevention
- Smoke-test credentials once at startup with a cheap endpoint (/3/configuration)
- Strip whitespace in .env values and quote JWTs (they contain no spaces but pasted newlines break them)
- Put v4 JWT in TMDB_ACCESS_TOKEN and 32-char v3 key in TMDB_API_KEY — never swapped
When it happens
Trigger: TMDB_ACCESS_TOKEN expired or regenerated in the TMDB dashboard (old token invalidated); a truncated copy-paste token (missing chars); sending a v3 api_key value in TMDB_ACCESS_TOKEN (it is not a JWT, server rejects); API key suspended for terms-of-service violations.
Common situations: Token rotated by another team member; token pasted with leading/trailing whitespace or quotes in .env; free-tier key disabled; key from a different TMDB account after config drift.
Related errors
- TMDB 未配置:请在 .env 设置 TMDB_ACCESS_TOKEN 或 TMDB_API_KEY
- TMDB 请求超时: {e}
- TMDB 网络错误: {e}
- 影片不存在或已下架
- TMDB 请求失败: HTTP {resp.status_code}, {resp.text[:200]}
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/f845c32630969b2b.
Report an issue: GitHub.