{"record":{"id":"5f1c3f4e2002966c","repo":"Budibase/budibase","slug":"microsoft-oauth-callback-is-missing-the-authorizat","errorCode":null,"errorMessage":"Microsoft OAuth callback is missing the authorization code","messagePattern":"Microsoft OAuth callback is missing the authorization code","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/server/src/api/controllers/ai/sharepointAuth.ts","lineNumber":126,"sourceCode":"  ) {\n    throw new Error(\"Microsoft OAuth state is invalid or expired\")\n  }\n  const appId = stateAppId\n\n  const oauthError = String(ctx.query.error || \"\").trim()\n  if (oauthError) {\n    const description = String(ctx.query.error_description || \"\").trim()\n    console.error(\"Microsoft OAuth authorization failed\", {\n      appId,\n      error: oauthError,\n      hasDescription: !!description,\n    })\n    throw new Error(\"Microsoft OAuth authorization failed\")\n  }\n\n  const code = String(ctx.query.code || \"\").trim()\n  if (!code) {\n    throw new Error(\n      \"Microsoft OAuth callback is missing the authorization code\"\n    )\n  }\n\n  const { clientId, clientSecret, tenantId } = getMicrosoftConfig()\n  const platformUrl = await configs.getPlatformUrl({ tenantAware: false })\n  const callbackUrl = `${platformUrl}/api/agent/knowledge-sources/sharepoint/callback`\n  const tokenEndpoint = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`\n\n  const tokenResponse = await fetch(tokenEndpoint, {\n    method: \"POST\",\n    headers: {\n      \"Content-Type\": \"application/x-www-form-urlencoded\",\n    },\n    body: new URLSearchParams({\n      client_id: clientId,\n      client_secret: clientSecret,\n      grant_type: \"authorization_code\",","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/ai/sharepointAuth.ts#L108-L144","documentation":"After a non-error callback, the controller requires an authorization `code` query parameter to exchange for tokens. If it is absent (after state and error checks pass), this Error is thrown.","triggerScenarios":"Microsoft redirects to the callback without a code (e.g. response_mode mismatch or silent failure), or the callback endpoint is invoked manually without ?code=.","commonSituations":"response_mode configured as fragment while the callback reads query params; Azure AD app config issues causing redirect without code; hand-crafted callback URLs in testing.","solutions":["Ensure the auth request uses response_mode=query (or the default) so the code arrives in the URL query string.","Verify the Azure AD redirect URI and platform config allow a standard authorization-code flow.","Restart the flow via the start endpoint rather than hitting the callback URL directly."],"exampleFix":"// before\nconst authUrl = `https://login.microsoftonline.com/${tenant}/oauth2/v2.0/authorize?...&response_mode=fragment`\n// after\nconst authUrl = `https://login.microsoftonline.com/${tenant}/oauth2/v2.0/authorize?...&response_mode=query&response_type=code`","handlingStrategy":"validation","validationCode":"const params = new URL(callbackUrl).searchParams\nif (!params.get('code')) throw new Error('callback URL must include the authorization code')","typeGuard":null,"tryCatchPattern":"try {\n  await completeSharePointAuth(ctx)\n} catch (e) {\n  if (e.message === 'Microsoft OAuth callback is missing the authorization code') {\n    // restart the flow with response_mode=query\n  } else throw e\n}","preventionTips":["Use response_mode=query and response_type=code in the authorize URL.","Never invoke the callback endpoint manually without completing the authorize step.","Confirm the Azure AD app is configured for authorization-code flow."],"tags":["oauth","microsoft","sharepoint","callback","missing-parameter"],"backgroundTag":"oauth-authorization-code-missing","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}