medusajs/medusa · critical · MedusaError

OIDC engine requires a 'client_id' option

Error message

OIDC engine requires a 'client_id' option

What it means

The OIDC engine requires a `client_id` identifying the application registered with the OIDC provider. The constructor throws INVALID_DATA at startup when it is missing.

Source

Thrown at packages/modules/providers/auth-oidc/src/engine/engine.ts:71

   * The memoized OIDC client. `openid-client` v5 caches the JWKS keystore per
   * `Issuer` instance, so building a fresh client on every call would refetch
   * the JWKS over HTTP on every login callback. The client is built lazily and
   * reused until the discovery cache entry expires; when all endpoints are
   * configured explicitly (no discovery), it's cached indefinitely, since the
   * engine's options are immutable per instance.
   */
  protected clientPromise_?: Promise<Client>
  protected clientExpiresAt_ = 0

  constructor(options: OidcEngineOptions, cache?: ICacheService) {
    if (!options?.issuer) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,
        "OIDC engine requires an 'issuer' option"
      )
    }
    if (!options.client_id) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,
        "OIDC engine requires a 'client_id' option"
      )
    }
    if (!options.callback_url) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,
        "OIDC engine requires a 'callback_url' option"
      )
    }

    assertSecureUrl(options.issuer, "issuer")
    for (const [key, value] of [
      ["authorization_endpoint", options.authorization_endpoint],
      ["token_endpoint", options.token_endpoint],
      ["jwks_uri", options.jwks_uri],
    ] as const) {
      if (value) {

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Register the app with the OIDC provider and pass its client_id in options
  2. Verify the env var is set where Medusa boots and matches the registered app exactly

Example fix

// before
{ id: 'oidc', resolve: '@medusajs/auth-oidc', options: { issuer } }
// after
{ id: 'oidc', resolve: '@medusajs/auth-oidc', options: { issuer, client_id: process.env.OIDC_CLIENT_ID, client_secret: process.env.OIDC_CLIENT_SECRET, callback_url } }
Defensive patterns

Strategy: validation

Validate before calling

for (const k of ['OIDC_ISSUER', 'OIDC_CLIENT_ID', 'OIDC_CLIENT_SECRET']) {
  if (!process.env[k]) throw new Error(`Missing env var: ${k}`)
}

Prevention

When it happens

Trigger: Configuring auth-oidc with an issuer but no client_id, or the OIDC_CLIENT_ID env var being undefined.

Common situations: Forgetting to register the app with the IdP, env var naming mismatch, or secrets not propagated to the deployment environment.

Related errors


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/7557d7894a740090. Report an issue: GitHub.