{"record":{"id":"9227392bb5d9c7da","repo":"Budibase/budibase","slug":"configuration-invalid-must-contain-google-clienti","errorCode":null,"errorMessage":"Configuration invalid. Must contain google clientID and clientSecret","messagePattern":"Configuration invalid\\. Must contain google clientID and clientSecret","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/backend-core/src/middleware/passport/sso/google.ts","lineNumber":57,"sourceCode":"    )\n  }\n}\n\n/**\n * Create an instance of the google passport strategy. This wrapper fetches the configuration\n * from couchDB rather than environment variables, using this factory is necessary for dynamically configuring passport.\n * @returns Dynamically configured Passport Google Strategy\n */\nexport async function strategyFactory(\n  config: GoogleInnerConfig,\n  callbackUrl: string,\n  saveUserFn: SaveSSOUserFunction\n) {\n  try {\n    const { clientID, clientSecret } = config\n\n    if (!clientID || !clientSecret) {\n      throw new Error(\n        \"Configuration invalid. Must contain google clientID and clientSecret\"\n      )\n    }\n\n    const verify = buildVerifyFn(saveUserFn)\n    return new GoogleStrategy(\n      {\n        clientID: config.clientID,\n        clientSecret: config.clientSecret,\n        callbackURL: callbackUrl,\n      },\n      verify\n    )\n  } catch (err: any) {\n    throw new Error(`Error constructing google authentication strategy: ${err}`)\n  }\n}\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/backend-core/src/middleware/passport/sso/google.ts#L39-L75","documentation":"strategyFactory builds a passport GoogleStrategy for SSO login and throws when the supplied config lacks a clientID or clientSecret. A valid Google OAuth client (both values from Google Cloud Console) is required to construct the strategy.","triggerScenarios":"Configuring Google SSO with only one of clientID/clientSecret, saving empty strings, or a corrupted/partial config document passed to strategyFactory during login.","commonSituations":"Admin saved the Google SSO form with a missing secret; Google Cloud OAuth client deleted/disabled so the secret was cleared; copying the clientID into the secret field; config created via API with omitted fields.","solutions":["Re-save Google SSO config with both clientID and clientSecret from Google Cloud Console","Reset the client secret in Google Cloud Console if lost, then update the config","Validate the config payload before saving (both fields non-empty strings)","Check the config document in the DB actually contains both keys (not just placeholders)"],"exampleFix":"// before\nawait config.save({ type: ConfigType.GOOGLE, config: { clientID } })\n// after\nawait config.save({ type: ConfigType.GOOGLE, config: { clientID, clientSecret: process.env.GOOGLE_CLIENT_SECRET } })","handlingStrategy":"validation","validationCode":"const { clientID, clientSecret } = config\nif (!clientID || !clientSecret) {\n  throw new Error(\"Google SSO requires both clientID and clientSecret\")\n}","typeGuard":"function isGoogleSsoConfig(c: unknown): c is { clientID: string; clientSecret: string } {\n  const cfg = c as { clientID?: string; clientSecret?: string }\n  return typeof cfg.clientID === \"string\" && cfg.clientID.length > 0 &&\n         typeof cfg.clientSecret === \"string\" && cfg.clientSecret.length > 0\n}","tryCatchPattern":null,"preventionTips":["Validate SSO config forms (required fields) before saving","Keep clientID/clientSecret sourced from env/secrets, not hand-typed values","Test SSO login after any config save or Google Cloud project change"],"tags":["google","oauth","sso","validation","missing-config"],"backgroundTag":"missing-oauth-configuration","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}