{"record":{"id":"8921f042305e2ee1","repo":"mastra-ai/mastra","slug":"slackprovider-baseurl-not-available-during-oauth-c","errorCode":null,"errorMessage":"SlackProvider baseUrl not available during OAuth callback","messagePattern":"SlackProvider baseUrl not available during OAuth callback","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"channels/slack/src/provider.ts","lineNumber":1406,"sourceCode":"\n    // Decrypt secrets for use\n    const pending = this.#decryptPendingInstallation(pendingEncrypted);\n\n    if (error) {\n      const errorUrl = pending.redirectUrl ?? this.#channelConfig.redirectPath ?? '/';\n      const redirect = new URL(errorUrl, c.req.url);\n      redirect.searchParams.set('channel_error', error);\n      redirect.searchParams.set('platform', 'slack');\n      return c.redirect(redirect.toString());\n    }\n\n    if (!code) {\n      return c.json({ error: 'Missing code parameter' }, 400);\n    }\n\n    const baseUrl = this.#getBaseUrl();\n    if (!baseUrl) {\n      throw new Error('SlackProvider baseUrl not available during OAuth callback');\n    }\n\n    try {\n      // Exchange code for tokens\n      const tokenResponse = await fetch('https://slack.com/api/oauth.v2.access', {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n        body: new URLSearchParams({\n          client_id: pending.clientId,\n          client_secret: pending.clientSecret,\n          code,\n          redirect_uri: `${baseUrl}/slack/oauth/callback`,\n        }),\n        signal: AbortSignal.timeout(30_000),\n      });\n\n      if (!tokenResponse.ok) {\n        throw new Error(`Slack OAuth HTTP error: ${tokenResponse.status} ${tokenResponse.statusText}`);","sourceCodeStart":1388,"sourceCodeEnd":1424,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/channels/slack/src/provider.ts#L1388-L1424","documentation":"During the Slack OAuth callback, the provider needs its own base URL to build redirect_uri and continue the flow. #getBaseUrl() returned nothing (provider never had baseUrl set and it couldn't be inferred from the request), so the provider throws rather than constructing a wrong redirect URI. This is an internal invariant: the OAuth exchange at slack.com/api/oauth.v2.access requires a redirect_uri that matches the one used to start the flow.","triggerScenarios":"Hitting the /slack/oauth/callback route while the SlackProvider's baseUrl is unset — e.g. provider mounted without configure({ baseUrl }) and the server can't derive the origin (proxied setup without forwarded headers, non-HTTP transport, or a callback invoked outside a normal HTTP request context).","commonSituations":"Running behind a reverse proxy that strips Host/X-Forwarded-* headers; testing the callback endpoint directly with curl (no Origin/host context); forgetting to pass baseUrl when constructing the provider for a deployment behind a custom domain.","solutions":["Pass an explicit baseUrl: provider.configure({ baseUrl: 'https://your-domain.com' }) or via the constructor.","Configure your proxy to forward Host and X-Forwarded-Proto headers so the server can infer the base URL.","Ensure the callback is reached via a normal HTTP request to the registered route, not invoked programmatically.","Verify the Slack app's redirect URL matches the same baseUrl used at install time."],"exampleFix":"// before\nconst provider = new SlackProvider({ refreshToken });\n// after\nconst provider = new SlackProvider({\n  refreshToken,\n  baseUrl: process.env.PUBLIC_BASE_URL ?? 'https://myapp.example.com',\n});","handlingStrategy":"validation","validationCode":"const baseUrl = process.env.PUBLIC_BASE_URL;\nif (!baseUrl) throw new Error('PUBLIC_BASE_URL must be set for Slack OAuth callbacks');\nprovider.configure({ baseUrl });","typeGuard":null,"tryCatchPattern":"try {\n  await handleSlackCallback(req);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('baseUrl not available')) {\n    console.error('Set baseUrl on SlackProvider / fix proxy forwarded headers');\n  } else throw e;\n}","preventionTips":["Always set an explicit baseUrl in deploy environments (don't rely on request inference).","Configure reverse proxies to forward Host and X-Forwarded-Proto headers.","Register the exact `${baseUrl}/slack/oauth/callback` redirect URL in the Slack app."],"tags":["slack","oauth","configuration","callback"],"backgroundTag":"missing-base-url","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}