{"record":{"id":"7557d7894a740090","repo":"medusajs/medusa","slug":"oidc-engine-requires-a-client-id-option","errorCode":null,"errorMessage":"OIDC engine requires a 'client_id' option","messagePattern":"OIDC engine requires a 'client_id' option","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"critical","filePath":"packages/modules/providers/auth-oidc/src/engine/engine.ts","lineNumber":71,"sourceCode":"   * The memoized OIDC client. `openid-client` v5 caches the JWKS keystore per\n   * `Issuer` instance, so building a fresh client on every call would refetch\n   * the JWKS over HTTP on every login callback. The client is built lazily and\n   * reused until the discovery cache entry expires; when all endpoints are\n   * configured explicitly (no discovery), it's cached indefinitely, since the\n   * engine's options are immutable per instance.\n   */\n  protected clientPromise_?: Promise<Client>\n  protected clientExpiresAt_ = 0\n\n  constructor(options: OidcEngineOptions, cache?: ICacheService) {\n    if (!options?.issuer) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        \"OIDC engine requires an 'issuer' option\"\n      )\n    }\n    if (!options.client_id) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        \"OIDC engine requires a 'client_id' option\"\n      )\n    }\n    if (!options.callback_url) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        \"OIDC engine requires a 'callback_url' option\"\n      )\n    }\n\n    assertSecureUrl(options.issuer, \"issuer\")\n    for (const [key, value] of [\n      [\"authorization_endpoint\", options.authorization_endpoint],\n      [\"token_endpoint\", options.token_endpoint],\n      [\"jwks_uri\", options.jwks_uri],\n    ] as const) {\n      if (value) {","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/providers/auth-oidc/src/engine/engine.ts#L53-L89","documentation":"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.","triggerScenarios":"Configuring auth-oidc with an issuer but no client_id, or the OIDC_CLIENT_ID env var being undefined.","commonSituations":"Forgetting to register the app with the IdP, env var naming mismatch, or secrets not propagated to the deployment environment.","solutions":["Register the app with the OIDC provider and pass its client_id in options","Verify the env var is set where Medusa boots and matches the registered app exactly"],"exampleFix":"// before\n{ id: 'oidc', resolve: '@medusajs/auth-oidc', options: { issuer } }\n// after\n{ id: 'oidc', resolve: '@medusajs/auth-oidc', options: { issuer, client_id: process.env.OIDC_CLIENT_ID, client_secret: process.env.OIDC_CLIENT_SECRET, callback_url } }","handlingStrategy":"validation","validationCode":"for (const k of ['OIDC_ISSUER', 'OIDC_CLIENT_ID', 'OIDC_CLIENT_SECRET']) {\n  if (!process.env[k]) throw new Error(`Missing env var: ${k}`)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register the app in the IdP first and copy credentials into secrets","Validate all OIDC options together at startup"],"tags":["oidc","oauth","auth-provider","module-config","startup"],"backgroundTag":"oauth-provider-misconfigured","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}