{"record":{"id":"c4b4101a7540684b","repo":"HeyPuter/puter","slug":"not-found-c4b410","errorCode":"not_found","errorMessage":"Provider not configured.","messagePattern":"Provider not configured\\.","errorType":"http","errorClass":"HttpError","httpStatus":404,"severity":"error","filePath":"src/backend/controllers/oidc/OIDCController.ts","lineNumber":272,"sourceCode":"                res.json({ providers });\n            },\n        );\n\n        // -- GET /auth/oidc/:provider/start --------------------------\n        // Redirect user to IdP authorization endpoint.\n\n        router.get(\n            '/auth/oidc/:provider/start',\n            {\n                subdomain: '',\n                rateLimit: { scope: 'oidc-general', limit: 30, window: 60_000 },\n            },\n            async (req: Request, res: Response) => {\n                const provider = String(req.params.provider);\n                const cfg =\n                    await this.services.oidc.getProviderConfig(provider);\n                if (!cfg)\n                    throw new HttpError(404, 'Provider not configured.', {\n                        legacyCode: 'not_found',\n                    });\n\n                const flow = String(\n                    Array.isArray(req.query.flow)\n                        ? req.query.flow[0]\n                        : (req.query.flow ?? 'login'),\n                );\n                const origin = (this.config.origin ?? '').replace(/\\/$/, '');\n\n                const flowRedirects: Record<string, string> = {\n                    login: origin || '/',\n                    signup: origin || '/',\n                    revalidate: `${origin}/auth/revalidate-done`,\n                };\n\n                let appRedirectUri = flowRedirects[flow] ?? (origin || '/');\n","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/controllers/oidc/OIDCController.ts#L254-L290","documentation":"`GET /auth/oidc/:provider/start` resolves the provider name from the URL path and looks up its configuration via `services.oidc.getProviderConfig()`. If no config exists for that provider ID, the endpoint returns 404. This means the provider is not enabled or the name is misspelled.","triggerScenarios":"Navigating to `/auth/oidc/google/start` when only `github` is configured; a typo in the provider slug; the provider was disabled in config after the frontend cached the link.","commonSituations":"Frontend hardcodes a provider list that drifts from the server config; a user bookmarks an old provider link; provider config was removed during a deployment but the UI wasn't updated.","solutions":["Check the enabled providers via `GET /auth/oidc/providers` and use only those IDs.","Verify the provider slug matches the config key exactly (case-sensitive).","If the provider should be available, add its config (client_id, client_secret, issuer URL) to the OIDC configuration.","Update the frontend to fetch the provider list dynamically rather than hardcoding."],"exampleFix":"// before — hardcoded provider link\n`/auth/oidc/google/start`\n\n// after — fetch enabled providers first\nconst { providers } = await fetch('/api/auth/oidc/providers').then(r => r.json());\n// providers: ['github', 'microsoft']\n`/auth/oidc/${providers[0]}/start`","handlingStrategy":"validation","validationCode":"// Fetch the enabled provider list before linking\nconst res = await fetch('/api/auth/oidc/providers');\nconst { providers } = await res.json();\n// providers: ['github', 'microsoft', ...]\nif (!providers.includes(requestedProvider)) {\n  console.error(`Provider '${requestedProvider}' is not available`);\n  return;\n}","typeGuard":"/** @param {unknown} v @returns {v is string[]} */\nfunction isStringArray(v) {\n  return Array.isArray(v) && v.every(x => typeof x === 'string');\n}","tryCatchPattern":"try {\n  window.location = `/auth/oidc/${provider}/start`;\n} catch (e) {\n  if (e.code === 'not_found') {\n    showProviderList(); // refresh available providers\n  }\n}","preventionTips":["Fetch the provider list dynamically from `/auth/oidc/providers` rather than hardcoding.","Update the UI when the provider list changes.","Match provider slugs case-sensitively against the server config."],"tags":["oidc","authentication","config","not-found","http-404"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}