bytedance/deer-flow · warning · HTTPException
Invalid provider ID
Error message
Invalid provider ID
What it means
400 from the OIDC login initiation: the {provider} path segment does not match _OIDC_PROVIDER_KEY_RE, a strict format pattern for provider keys (lowercase alphanumeric/kebab-style identifiers). This is lexical validation only — it fires before the provider lookup, so even a configured provider with an odd-shaped key would be unreachable via this route.
Source
Thrown at backend/app/gateway/routers/auth.py:672
next: str | None = None, # noqa: A002 (shadowing built-in is intentional — this is the query param name)
remember_me: bool = True,
):
"""Initiate OIDC login flow.
Redirects to the OIDC provider's authorization URL with state, nonce,
and PKCE parameters. The ``next`` query parameter specifies where to
redirect after successful login (default: /workspace).
"""
from deerflow.config.app_config import get_app_config
app_config = get_app_config()
oidc_config = app_config.auth.oidc
if not oidc_config.enabled:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="SSO authentication is not enabled")
if not _OIDC_PROVIDER_KEY_RE.match(provider):
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid provider ID")
provider_config = oidc_config.providers.get(provider)
if not provider_config:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Unknown SSO provider: {provider}")
# Validate `next` / open redirect prevention
redirect_path = validate_next_param(next) or "/workspace"
# Resolve redirect URI
redirect_uri = _resolve_oidc_redirect_uri(request, provider, provider_config)
# Generate state, nonce, PKCE
state_value = generate_oidc_state()
nonce_value = generate_nonce() if provider_config.nonce_enabled else None
code_verifier = generate_code_verifier() if provider_config.pkce_enabled else None
code_challenge = compute_code_challenge(code_verifier) if code_verifier else None
# Get provider metadata via discoveryView on GitHub (pinned to 1dd6ba1acb)
Solutions
- Use the exact provider key from auth.oidc.providers in config.yaml, in its canonical lowercase form
- Rename the config key to match the allowed syntax (letters/digits/hyphens) if it currently contains other characters
- URL-encode nothing extra: pass the plain key as the path segment
Example fix
# config.yaml + request — before
providers:
My_Provider: {...}
GET /api/auth/oidc/My_Provider/login # 400
# after
providers:
my-provider: {...}
GET /api/auth/oidc/my-provider/login # proceeds to redirect Defensive patterns
Strategy: validation
Validate before calling
const PROVIDER_KEY_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
if (!PROVIDER_KEY_RE.test(provider)) throw new Error(`Invalid provider key: ${provider}`); Type guard
function isValidProviderKey(key: string): boolean {
return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(key);
} Try / catch
try { await startOidcLogin(provider); } catch (e) { if (e.status === 400 && /Invalid provider/.test(e.message)) { correctProviderKey(); return; } throw e; } Prevention
- Name provider keys in config using lowercase letters, digits, and hyphens only
- Pass the config key verbatim as the path segment — never display names or issuer hostnames
When it happens
Trigger: GET /api/auth/oidc/{provider}/login with a provider containing uppercase, spaces, slashes, URL-encoded characters, or other characters outside the allowed key syntax (e.g. 'My_Provider' or 'prov%20ider').
Common situations: Provider keys defined in config with underscores or capitals that the regex rejects; clients passing display names or issuer hostnames instead of the configured key; path-encoding mistakes.
Related errors
- Unknown SSO provider: {provider}
- Missing code or state parameter
- Unable to recover SSE history after ${recoveryAttempts} atte
- Your email could not be verified by the identity provider. P
- The identity provider did not provide an email address.
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/4158b8b961b92090.
Report an issue: GitHub.