different-ai/openwork · error
OIDC discovery document is missing required endpoints.
Error message
OIDC discovery document is missing required endpoints.
What it means
After fetching the discovery document, the response body is parsed with oidcDiscoverySchema. If the JSON lacks the required endpoint fields (or has wrong types), safeParse fails and this Error is thrown, meaning the document exists but is not a usable OIDC discovery payload.
Source
Thrown at ee/apps/den-api/src/sso.ts:127
authorizationEndpoint: input.authorizationEndpoint,
tokenEndpoint: input.tokenEndpoint,
jwksEndpoint: input.jwksEndpoint,
userInfoEndpoint: input.userInfoEndpoint ?? undefined,
tokenEndpointAuthentication: input.tokenEndpointAuthentication ?? undefined,
}
}
const response = await fetch(getOidcDiscoveryUrl(input.issuer), {
headers: { accept: "application/json" },
signal: AbortSignal.timeout(10_000),
})
if (!response.ok) {
throw new Error(`OIDC discovery failed with ${response.status}. Enter manual OIDC endpoints or enable skip discovery.`)
}
const parsed = oidcDiscoverySchema.safeParse(await response.json())
if (!parsed.success) {
throw new Error("OIDC discovery document is missing required endpoints.")
}
if (normalizeIssuer(parsed.data.issuer) !== normalizeIssuer(input.issuer)) {
throw new Error("OIDC discovery issuer does not match the configured issuer.")
}
return {
skipDiscovery: true,
authorizationEndpoint: parsed.data.authorization_endpoint,
tokenEndpoint: parsed.data.token_endpoint,
jwksEndpoint: parsed.data.jwks_uri,
userInfoEndpoint: parsed.data.userinfo_endpoint,
tokenEndpointAuthentication: input.tokenEndpointAuthentication ?? undefined,
}
}
async function getSsoProviderByProviderId(providerId: string) {
const rows = await db
.select()View on GitHub (pinned to 2b7df46e8a)
Solutions
- Confirm the IdP supports OpenID Connect discovery and its document includes authorization_endpoint, token_endpoint, and jwks_uri
- If it is plain OAuth2, enter the endpoints manually with skipDiscovery: true
- curl the discovery URL and inspect the JSON body for a proxy or error page
Example fix
// before
// discovery returns { issuer: '...', authorization_endpoint: '...' } // missing token/jwks
// after
{ issuer: 'https://idp.example.com', skipDiscovery: true, authorizationEndpoint: 'https://idp.example.com/authorize', tokenEndpoint: 'https://idp.example.com/token', jwksEndpoint: 'https://idp.example.com/.well-known/jwks.json' } Defensive patterns
Strategy: validation
Validate before calling
const res = await fetch(getOidcDiscoveryUrl(issuer), { headers: { accept: 'application/json' } })
const body = await res.json()
const required = ['authorization_endpoint', 'token_endpoint', 'jwks_uri'] as const
const missing = required.filter((k) => typeof body?.[k] !== 'string' || !body[k])
if (missing.length) throw new Error(`Discovery document missing: ${missing.join(', ')}`) Type guard
function isOidcDiscoveryDocument(v: unknown): v is { authorization_endpoint: string; token_endpoint: string; jwks_uri: string } {
const d = v as Record<string, unknown>
return typeof d.authorization_endpoint === 'string' && typeof d.token_endpoint === 'string' && typeof d.jwks_uri === 'string'
} Try / catch
try {
await resolveOidcEndpoints(input)
} catch (e) {
if (e instanceof Error && e.message === 'OIDC discovery document is missing required endpoints.') {
// provider lacks OIDC metadata; switch to manual endpoints
} else throw e
} Prevention
- Confirm the provider is OpenID Connect (not plain OAuth2) before relying on discovery
- curl the discovery URL and eyeball required fields when onboarding a new IdP
- Prefer manual endpoint configuration for non-standard providers
When it happens
Trigger: Discovery endpoint returns 200 with JSON missing authorization_endpoint, token_endpoint, or jwks_uri fields, or returning a non-JSON body (HTML error page, OAuth 2.0-only metadata).
Common situations: Plain OAuth2 server without OpenID Connect discovery fields; IdP serving an HTML login/error page with 200; truncated or proxied response; wrong URL returning some other JSON API's output.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- OIDC discovery failed with ${response.status}. Enter manual
- Manual OIDC configuration requires authorization, token, and
- OIDC discovery issuer does not match the configured issuer.
- Failed to save SSO settings (${response.status}).
- invalid_session_payload
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/d86163c7ebc864a0.
Report an issue: GitHub.