Budibase/budibase · error · HTTPError
Failed to exchange Slack OAuth code
Error message
Failed to exchange Slack OAuth code
What it means
This error is thrown by exchangeSlackOAuthCode when Slack's oauth.v2.access endpoint responds with a non-ok HTTP status during authorization code exchange. The code exchange turns a temporary OAuth code into bot tokens using client_id/client_secret/redirect_uri; an HTTP-level failure means the request was rejected before Slack returned a structured ok:false payload.
Source
Thrown at packages/server/src/sdk/workspace/ai/deployments/slack.ts:242
clientId: string
clientSecret: string
redirectUri: string
}) => {
const response = await fetch(`${SLACK_API_BASE}/oauth.v2.access`, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
code,
client_id: clientId,
client_secret: clientSecret,
redirect_uri: redirectUri,
}),
})
const payload = (await response.json()) as SlackOAuthAccessResponse
if (!response.ok) {
throw new HTTPError("Failed to exchange Slack OAuth code", response.status)
}
return assertSlackOk(payload, "Failed to exchange Slack OAuth code")
}
export const rotateSlackConfigToken = async ({
refreshToken,
}: {
refreshToken: string
}) => {
const response = await fetch(`${SLACK_API_BASE}/tooling.tokens.rotate`, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
refresh_token: refreshToken,
}),
})View on GitHub (pinned to a81a902e9a)
Solutions
- Verify client_id and client_secret match the Slack app's 'Basic Information' credentials exactly.
- Ensure redirect_uri is byte-for-byte identical to one of the redirect URLs registered in the Slack app's OAuth settings.
- Restart the OAuth flow so the user authorizes again and a fresh single-use code is issued.
- If the status is 5xx, retry after a short delay (transient Slack issue).
Example fix
// before
await exchangeSlackOAuthCode({ code, clientId, clientSecret, redirectUri })
// after - make sure redirectUri matches Slack app settings exactly
await exchangeSlackOAuthCode({
code,
clientId: process.env.SLACK_CLIENT_ID,
clientSecret: process.env.SLACK_CLIENT_SECRET,
redirectUri: "https://your-host.example.com/api/webhooks/slack/oauth/callback"
}) Defensive patterns
Strategy: validation
Validate before calling
if (!clientId || !clientSecret) throw new Error("Slack client credentials missing")
if (redirectUri !== REGISTERED_SLACK_REDIRECT_URI) {
throw new Error("redirect_uri must exactly match a redirect URL registered in the Slack app")
} Try / catch
try {
const tokens = await exchangeSlackOAuthCode({ code, clientId, clientSecret, redirectUri })
} catch (e) {
if (e instanceof HTTPError && e.status === 400) {
// verify credentials/redirect_uri, then restart OAuth flow for a fresh code
}
throw e
} Prevention
- Keep the redirect_uri in one shared constant that matches the Slack app configuration exactly.
- Never reuse OAuth codes; start a new authorization when in doubt.
- Load client_id/client_secret from env/secret manager and verify at startup.
When it happens
Trigger: POSTing the OAuth code exchange to Slack and receiving 4xx/5xx - e.g. wrong client credentials causing 400 invalid_client, a redirect_uri that does not exactly match the registered request URI, or network-level 5xx from Slack.
Common situations: redirect_uri mismatch between the Budibase OAuth initiation and the Slack app's registered redirect URLs; copy-paste errors in client_id/client_secret; exchanging a code twice (second attempt may fail at HTTP level depending on timing); Slack outage.
Related errors
- Failed to rotate Slack app configuration token
- Slack app creation response was incomplete
- Slack OAuth callback is missing state
- Slack OAuth state is invalid or expired
- Slack OAuth authorization failed
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/165a33db77a37c58.
Report an issue: GitHub.