{"record":{"id":"79aa1d0088d2ad26","repo":"gitroomhq/postiz-app","slug":"auth-provider-provider-not-found","errorCode":null,"errorMessage":"Auth provider ${provider} not found","messagePattern":"Auth provider (.+?) not found","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/backend/src/services/auth/providers/providers.manager.ts","lineNumber":18,"sourceCode":"import { Injectable } from '@nestjs/common';\nimport { ModuleRef } from '@nestjs/core';\nimport { AuthProviderAbstract } from '@gitroom/backend/services/auth/providers.interface';\n\n@Injectable()\nexport class AuthProviderManager {\n  constructor(private _moduleRef: ModuleRef) {}\n\n  getProvider(provider: string): AuthProviderAbstract {\n    const metadata =\n      Reflect.getMetadata('auth-provider', AuthProviderAbstract) || [];\n\n    const found = metadata.find(\n      (m: any) => m.provider === provider\n    );\n\n    if (!found) {\n      throw new Error(`Auth provider ${provider} not found`);\n    }\n\n    return this._moduleRef.get(found.target, { strict: false });\n  }\n}\n","sourceCodeStart":1,"sourceCodeEnd":24,"githubUrl":"https://github.com/gitroomhq/postiz-app/blob/0f1647f7491a217d43eb5ae7a480484bdf0aff3e/apps/backend/src/services/auth/providers/providers.manager.ts#L1-L24","documentation":"The auth ProvidersManager scans registered provider modules and looks up the one whose metadata `provider` equals the requested provider string. If no module declares that provider identifier, it throws before resolving the implementation from the NestJS moduleRef.","triggerScenarios":"Calling checkExists/OAuth flow with a provider value that no decorated provider module registers (e.g. 'facebook' when only a subset of provider modules are imported into the AuthModule), or a typo/casing mismatch in the provider param.","commonSituations":"New provider added to the frontend dropdown but its module isn't registered in the backend auth module; provider string casing mismatch ('Apple' vs 'apple'); conditional compilation/exclusion of provider modules per deployment; stale enum vs registered metadata divergence after a refactor.","solutions":["Check which provider modules are imported in the Auth/Providers module and add the missing provider module","Verify the provider string matches the metadata exactly (case-sensitive compare against the @Provider('x') decoration)","Guard the endpoint/controller with an allowed-providers check so unknown values 400 early instead of 500","If a provider was intentionally removed, remove it from the frontend provider list too"],"exampleFix":"// before\n@Module({ imports: [AppleProviderModule, GoogleProviderModule] })\nclass AuthModule {}\n// request with provider='discord' -> 'Auth provider discord not found'\n\n// after\n@Module({ imports: [AppleProviderModule, GoogleProviderModule, DiscordProviderModule] })\nclass AuthModule {}","handlingStrategy":"type-guard","validationCode":"const registered = await providersApi.list(); // or a static list\nif (!registered.includes(provider)) {\n  throw new BadRequestException(`Unsupported provider: ${provider}`);\n}\nawait authService.checkExists({ provider, code, state });","typeGuard":"const SUPPORTED_PROVIDERS = ['apple', 'google', 'facebook'] as const;\nconst isSupportedProvider = (p: string): p is typeof SUPPORTED_PROVIDERS[number] =>\n  (SUPPORTED_PROVIDERS as readonly string[]).includes(p);","tryCatchPattern":"try {\n  await authService.checkExists({ provider, code, state });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('not found')) {\n    return res.status(400).json({ error: `Unsupported provider ${provider}` });\n  }\n  throw e;\n}","preventionTips":["Validate the provider param against the registry before the OAuth flow starts","Keep the frontend provider list generated from the backend's registered providers","Register every new provider module in the auth module at integration time"],"tags":["oauth","provider-registry","di","configuration"],"backgroundTag":"oauth-provider-not-registered","analyzedSha":"0f1647f7491a217d43eb5ae7a480484bdf0aff3e","analyzedAt":"2026-08-27T12:09:55.020Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}