Budibase/budibase · warning · Error
Slack OAuth authorization failed
Error message
Slack OAuth authorization failed
What it means
After validating state, completeSlackOAuth checks the callback query for an error parameter, which Slack sets when the user denies the app or authorization fails. If present, it throws this Error to surface the upstream authorization failure.
Source
Thrown at packages/server/src/api/controllers/ai/agents.ts:587
export async function completeSlackOAuth(ctx: UserCtx<void, void>) {
const state = String(ctx.query.state || "").trim()
if (!state) {
throw new Error("Slack OAuth callback is missing state")
}
const cacheKey = getSlackOAuthStateCacheKey(state)
const statePayload = (await cache.get(cacheKey, {
useTenancy: false,
})) as SlackOAuthState | undefined
await cache.destroy(cacheKey, { useTenancy: false })
if (!statePayload?.agentId || !statePayload.workspaceId) {
throw new Error("Slack OAuth state is invalid or expired")
}
const oauthError = String(ctx.query.error || "").trim()
if (oauthError) {
throw new Error("Slack OAuth authorization failed")
}
const code = String(ctx.query.code || "").trim()
if (!code) {
throw new Error("Slack OAuth callback is missing the authorization code")
}
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,View on GitHub (pinned to a81a902e9a)
Solutions
- Retry the install and click 'Allow' on the Slack consent screen
- If Slack demands admin approval, have a workspace admin approve the app installation then retry
- Verify the app's scopes and distribution settings in the Slack app configuration
- Surface the error query value to the end user so they know why authorization failed
Defensive patterns
Strategy: try-catch
Validate before calling
const oauthError = new URL(callbackUrl).searchParams.get("error")
if (oauthError) {
// show user-facing message before invoking the callback handler
return { ok: false, reason: oauthError }
} Try / catch
try {
await completeSlackOAuth(ctx)
} catch (err) {
if (err.message === "Slack OAuth authorization failed") {
// user denied the app or Slack returned error=; show a friendly restart-install message
} else { throw err }
} Prevention
- Tell users ahead of time that cancelling the Slack consent screen aborts the install
- Handle the error query param in the client callback UI with a clear message
- Check app distribution/approval settings so installs are not silently blocked
- Read ctx.query.error to display Slack's specific denial reason
When it happens
Trigger: Slack redirects back to the callback with ?error=... (or error=subdomain etc.) — the end user clicked 'Cancel' on the Slack consent screen, the app was rejected, or Slack refused the authorize request.
Common situations: User cancels the Slack permission screen; workspace requires admin app approval and it was denied; app not approved/distributed for that workspace; Slack-side policy blocking installation.
Related errors
- Slack app creation response was incomplete
- Slack OAuth callback is missing state
- Slack OAuth state is invalid or expired
- Slack OAuth callback is missing the authorization code
- Slack OAuth client credentials are not configured
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/514ed7a46b74530c.
Report an issue: GitHub.