Budibase/budibase · error · Error
Slack OAuth response did not include a bot token
Error message
Slack OAuth response did not include a bot token
What it means
After exchanging the authorization code via sdk.ai.deployments.slack.exchangeSlackOAuthCode, the handler expects token.access_token (the Slack bot token, xoxb-...). If the exchange response has no access_token, it throws this Error since the agent cannot operate without a bot token.
Source
Thrown at packages/server/src/api/controllers/ai/agents.ts:612
await context.doInWorkspaceContext(statePayload.workspaceId, async () => {
const agent = await sdk.ai.agents.getOrThrow(statePayload.agentId)
const clientId = agent.slackIntegration?.clientId?.trim()
const clientSecret = agent.slackIntegration?.clientSecret?.trim()
if (!clientId || !clientSecret) {
throw new Error("Slack OAuth client credentials are not configured")
}
const redirectUri = await getSlackOAuthRedirectUrl()
const token = await sdk.ai.deployments.slack.exchangeSlackOAuthCode({
code,
clientId,
clientSecret,
redirectUri,
})
const botToken = token.access_token?.trim()
if (!botToken) {
throw new Error("Slack OAuth response did not include a bot token")
}
const updatedAgent = await sdk.ai.agents.update({
...agent,
slackIntegration: {
...agent.slackIntegration,
appId: token.app_id?.trim() || agent.slackIntegration?.appId,
botToken,
botUserId: token.bot_user_id?.trim() || undefined,
teamId: token.team?.id?.trim() || undefined,
teamName: token.team?.name?.trim() || undefined,
},
})
await publishSlackIntegrationForLiveAgent(updatedAgent)
})
ctx.redirect(
`/builder/workspace/${statePayload.workspaceId}/agent/${statePayload.agentId}/deployment?slack_connected=1`View on GitHub (pinned to a81a902e9a)
Solutions
- Log the full exchange response — it usually contains an 'error' field (invalid_code, bad_redirect_uri, etc.) explaining the failure
- Restart the OAuth flow so a fresh, unused code is exchanged
- Ensure the redirectUri passed to exchangeSlackOAuthCode exactly matches the one used in the authorize URL and Slack app settings
- Verify clientId/clientSecret are correct and the Slack app has bot token scopes configured
Defensive patterns
Strategy: try-catch
Validate before calling
const token = await sdk.ai.deployments.slack.exchangeSlackOAuthCode({ code, clientId, clientSecret, redirectUri })
if (!token.access_token?.trim()) {
// inspect token.error (e.g. invalid_code, bad_redirect_uri) before updating the agent
console.error("Slack token exchange failed:", token)
} Type guard
function hasBotToken(t: { access_token?: string }): t is { access_token: string } {
return typeof t.access_token === "string" && t.access_token.trim() !== ""
} Try / catch
try {
await completeSlackOAuth(ctx)
} catch (err) {
if (err.message.includes("did not include a bot token")) {
// log exchange response error field, restart OAuth with a fresh code and matching redirect_uri
} else { throw err }
} Prevention
- Ensure redirectUri in the exchange matches the authorize request and Slack app settings exactly
- Only exchange fresh codes — never reuse a code from a previous callback
- Verify Slack app bot scopes are configured so v2 access returns a bot token
- Capture and log the full exchange response for diagnosis (redacting secrets)
When it happens
Trigger: Slack's oauth.v2.access response lacks access_token — the code was invalid/already used (Slack returns ok:false with an error field instead), wrong clientId/clientSecret, redirect_uri mismatch with the one used at authorize time, or missing scope grant for a bot token.
Common situations: Replayed/expired authorization code; redirect_uri passed to the exchange differing from the authorize request; Slack app missing bot scopes/incorrect app type; Slack API incident returning malformed responses.
Related errors
- Slack app creation response was incomplete
- Slack OAuth callback is missing state
- Slack OAuth state is invalid or expired
- Slack OAuth authorization failed
- Slack OAuth callback is missing the authorization code
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/96a6673d47f43f19.
Report an issue: GitHub.