{"record":{"id":"b27e6ce19864b767","repo":"Budibase/budibase","slug":"unable-to-retrieve-datasource-authentication-cooki","errorCode":null,"errorMessage":"Unable to retrieve datasource authentication cookie","messagePattern":"Unable to retrieve datasource authentication cookie","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/worker/src/api/controllers/global/auth.ts","lineNumber":310,"sourceCode":"    ctx,\n    {\n      provider,\n      appId: ctx.query.appId,\n      returnPath,\n    },\n    Cookie.DatasourceAuth\n  )\n\n  return handler.preAuth(passport, ctx, next)\n}\n\nexport const datasourceAuth = async (ctx: UserCtx<void, void>, next: Next) => {\n  const authStateCookie = getCookie<DatasourceAuthCookie>(\n    ctx,\n    Cookie.DatasourceAuth\n  )\n  if (!authStateCookie) {\n    throw new Error(\"Unable to retrieve datasource authentication cookie\")\n  }\n  const provider = authStateCookie.provider\n  const { middleware } = require(`@budibase/backend-core`)\n  const handler = middleware.datasource[provider]\n  if (!handler) {\n    ctx.throw(400, \"Unsupported datasource provider\")\n  }\n  return handler.postAuth(passport, ctx, next)\n}\n\n// GOOGLE SSO\n\nexport async function googleCallbackUrl(config?: GoogleInnerConfig) {\n  return ssoCallbackUrl(ConfigType.GOOGLE, config)\n}\n\n/**\n * The initial call that google authentication makes to take you to the google login screen.","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/worker/src/api/controllers/global/auth.ts#L292-L328","documentation":"datasourceAuth middleware handles the OAuth callback for datasource logins. It reads a DatasourceAuth cookie that was set when the flow started; if the cookie is absent the middleware cannot determine which provider handler to invoke and throws immediately.","triggerScenarios":"Hitting the datasource auth callback endpoint without a DatasourceAuth cookie: the cookie expired, was blocked/cleared by the browser, was stripped by cross-site cookie policies, or the endpoint was opened directly instead of through the OAuth flow.","commonSituations":"Third-party cookie blocking in Safari/incognito, redirect flows crossing different domains so the cookie is not sent, long-running OAuth flows outlasting cookie expiry, users bookmarking or sharing the callback URL.","solutions":["Restart the datasource OAuth flow from the beginning so a fresh DatasourceAuth cookie is set","Check browser cookie settings / disable third-party cookie blocking for the Budibase domain","Ensure the OAuth provider redirect stays on the same domain so the cookie is transmitted","Confirm the time between initiating auth and callback is shorter than the cookie expiry"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const cookie = ctx.cookies.get(Cookie.DatasourceAuth)\nif (!cookie) {\n  // redirect to re-initiate the datasource OAuth flow instead of proceeding\n  return ctx.redirect(\"/api/datasources/auth/init\")\n}","typeGuard":"function hasDatasourceAuthCookie(c: unknown): c is DatasourceAuthCookie {\n  return c != null && typeof c === \"object\" && \"provider\" in c\n}","tryCatchPattern":null,"preventionTips":["Always start the flow via the endpoint that sets the DatasourceAuth cookie","Keep the OAuth flow on the same domain to avoid cookie loss from third-party blocking","Don't bookmark/share callback URLs directly","Keep flows short to avoid cookie expiry mid-flow"],"tags":["oauth","cookies","authentication","middleware"],"backgroundTag":"missing-auth-cookie","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}