Budibase/budibase · error · HTTPError

Slack app configuration token has expired. Save a new config

Error message

Slack app configuration token has expired. Save a new config token and refresh token.

What it means

This HTTP 400 error is thrown by assertSlackOk when a Slack API response returns ok:false with error 'token_expired'. Budibase uses Slack app configuration tokens (app config tokens with refresh tokens) for manifest-based app creation; these tokens expire and must be rotated. The message instructs you to save a new config token and refresh token pair.

Source

Thrown at packages/server/src/sdk/workspace/ai/deployments/slack.ts:175

    name?: string
  }
}

interface SlackConfigTokenRotateResponse extends SlackApiResponse {
  token?: string
  refresh_token?: string
  exp?: number
}

const assertSlackOk = <T extends SlackApiResponse>(
  payload: T,
  action: string
) => {
  if (payload.ok) {
    return payload
  }
  if (payload.error === "token_expired") {
    throw new HTTPError(
      "Slack app configuration token has expired. Save a new config token and refresh token.",
      400
    )
  }
  if (payload.error === "invalid_refresh_token") {
    throw new HTTPError(
      "Slack app configuration refresh token is invalid. Save a new config token and refresh token.",
      400
    )
  }
  const details = payload.errors?.map(error => error.message).filter(Boolean)
  const message = details?.length
    ? `${action}: ${details.join(", ")}`
    : `${action}: ${payload.error || "unknown_error"}`
  throw new HTTPError(message, 400)
}

export const createSlackAppFromManifest = async ({

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Obtain a fresh Slack app configuration token and refresh token from the Slack app setup flow, then save both via the agent's Slack integration settings.
  2. Call rotateSlackConfigToken with a valid refresh token to mint a new access token before retrying the operation.
  3. Re-run the Slack OAuth/app-manifest setup from the Budibase UI to regenerate tokens end-to-end.
  4. If refresh also fails with invalid_refresh_token, restart the full Slack app setup (see error 495).

Example fix

// before
await createSlackAppFromManifest({ configToken: staleToken, manifest }) // token_expired
// after
const rotated = await rotateSlackConfigToken({ refreshToken: storedRefreshToken })
await createSlackAppFromManifest({ configToken: rotated.configToken, manifest })
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await createSlackAppFromManifest({ configToken, manifest })
} catch (e) {
  if (e instanceof HTTPError && e.message.includes("token has expired")) {
    const rotated = await rotateSlackConfigToken({ refreshToken })
    await createSlackAppFromManifest({ configToken: rotated.configToken, manifest })
  } else throw e
}

Prevention

When it happens

Trigger: Calling createSlackAppFromManifest, exchangeSlackOAuthCode, or rotated() with a Slack configuration access token that Slack has expired - e.g. deploying/creating a Slack app with a config token captured hours/days earlier that has since expired.

Common situations: Config token stored in the agent/environment long ago and never refreshed; token rotation failed silently in a previous run; a stale token was copied from old documentation or a teammate's expired setup.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/42da8cef2cc2575e. Report an issue: GitHub.