Budibase/budibase · error · HTTPError

Slack app configuration token is required

Error message

Slack app configuration token is required

What it means

Saving a Slack app configuration requires a non-empty config token; the save() function in slackAppConfig.ts trims both incoming tokens and throws this 400 HTTPError when the config token is empty/whitespace-only. This guard runs before any Slack token rotation or DB write, so an invalid config never reaches storage.

Source

Thrown at packages/server/src/sdk/workspace/ai/slackAppConfig.ts:115

      )
    }
    return decodeSecret(config.configToken)
  }

  const rotated = await rotateSlackConfigToken({
    refreshToken: decodeSecret(config.refreshToken),
  })
  return decodeSecret((await saveRotatedConfig(config, rotated)).configToken)
}

export const save = async (configToken: string, refreshToken: string) => {
  const db = getWorkspaceDB()
  const existing = await fetch()
  const now = new Date().toISOString()
  const trimmedToken = configToken.trim()
  const trimmedRefreshToken = refreshToken.trim()
  if (!trimmedToken) {
    throw new HTTPError("Slack app configuration token is required", 400)
  }
  if (!trimmedRefreshToken) {
    throw new HTTPError(
      "Slack app configuration refresh token is required",
      400
    )
  }
  if (trimmedToken === PASSWORD_REPLACEMENT && !existing?.configToken) {
    throw new HTTPError("Slack app configuration token is required", 400)
  }
  if (trimmedRefreshToken === PASSWORD_REPLACEMENT && !existing?.refreshToken) {
    throw new HTTPError(
      "Slack app configuration refresh token is required",
      400
    )
  }

  const rotated = await rotateSlackConfigToken({

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Provide the actual Slack app configuration token (bot/user token from the Slack app config) in the request body and retry.
  2. Check the client form/field binding so the token input is actually submitted with the request.
  3. Trim-check the value client-side before calling the save endpoint and surface a validation error instead.

Example fix

// before
await sdk.ai.slackAppConfig.save("", refreshToken)
// after
await sdk.ai.slackAppConfig.save("xoxb-config-token", refreshToken)
Defensive patterns

Strategy: validation

Validate before calling

if (!configToken || !configToken.trim()) throw new Error("configToken is required")
await sdk.ai.slackAppConfig.save(configToken, refreshToken)

Type guard

const hasToken = (v: unknown): v is string => typeof v === "string" && v.trim().length > 0

Try / catch

try {
  await sdk.ai.slackAppConfig.save(configToken, refreshToken)
} catch (e) {
  if (e instanceof HTTPError && e.status === 400) {
    // surface "config token required" to the user / re-prompt for the token
  }
  throw e
}

Prevention

When it happens

Trigger: Calling save(configToken, refreshToken) (exposed via the Slack app config API endpoint) with configToken being "" or whitespace-only (e.g. " ").

Common situations: Developer cleared the token field in the UI and submitted; form binding failed so the token arrived empty; env/config value was never set before calling the endpoint.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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