Budibase/budibase · error · Error
Slack OAuth callback is missing the authorization code
Error message
Slack OAuth callback is missing the authorization code
What it means
On a successful (non-error) callback, Slack returns ?code=... which is exchanged for a bot token. If the code parameter is missing or empty despite no error being present, the handler throws this Error because the token exchange cannot proceed.
Source
Thrown at packages/server/src/api/controllers/ai/agents.ts:592
}
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,
clientId,
clientSecret,
redirectUri,
})
const botToken = token.access_token?.trim()View on GitHub (pinned to a81a902e9a)
Solutions
- Restart the OAuth flow from initiation — authorization codes are single-use and short-lived
- Verify the Slack app's redirect URL matches exactly and does not get rewritten by proxies
- Ensure the authorize URL requests the expected response_type=code flow
- Log the full callback query server-side to see what Slack actually returned
Defensive patterns
Strategy: validation
Validate before calling
const url = new URL(callbackUrl)
if (!url.searchParams.get("error") && !url.searchParams.get("code")) {
throw new Error("Callback has neither code nor error — restart the OAuth flow")
} Type guard
function hasOAuthCode(q: Record<string, unknown>): q is Record<string, string> & { code: string } {
return typeof q.code === "string" && q.code.trim() !== ""
} Try / catch
try {
await completeSlackOAuth(ctx)
} catch (err) {
if (err.message.includes("missing the authorization code")) {
// restart flow; codes are single-use so retrying the callback never works
} else { throw err }
} Prevention
- Never retry a consumed callback — always re-initiate for a fresh code
- Verify redirect URL configuration so Slack returns the full query string
- Avoid URL rewriting middleware on the callback route
- Log callback query keys (not values) to diagnose stripped params
When it happens
Trigger: Callback arrives with neither error nor code — truncated redirect URL, duplicate query handling, Slack returning an unexpected redirect shape, or the user re-submitting a callback whose code was already consumed/stripped.
Common situations: Proxies rewriting the redirect and dropping query params; users re-opening a callback URL from history after the code was used; misconfigured redirect URL in the Slack app settings.
Related errors
- Slack OAuth callback is missing state
- Slack app creation response was incomplete
- Slack OAuth state is invalid or expired
- Slack OAuth authorization failed
- Slack OAuth client credentials are not configured
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/8402c03d416d6da5.
Report an issue: GitHub.