Budibase/budibase · error · HTTPError

Slack integration requires botToken and signingSecret

Error message

Slack integration requires botToken and signingSecret

What it means

This HTTP 400 error is thrown by validateSlackIntegration when the agent has a slackIntegration object but either botToken or signingSecret is missing or blank after trimming. Both credentials are required: the bot token authenticates Slack API calls and the signing secret verifies incoming Slack webhook requests.

Source

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

  return truncate(safeName || "budibase-agent", MAX_BOT_DISPLAY_NAME_LENGTH)
}

export const validateSlackIntegration = (
  agent: Agent
): ResolvedSlackIntegration => {
  const integration = agent.slackIntegration
  if (!integration) {
    throw new HTTPError(
      "Slack integration is not configured for this agent",
      400
    )
  }

  const botToken = integration.botToken?.trim()
  const signingSecret = integration.signingSecret?.trim()

  if (!botToken || !signingSecret) {
    throw new HTTPError(
      "Slack integration requires botToken and signingSecret",
      400
    )
  }

  return {
    botToken,
    signingSecret,
  }
}

export const buildSlackWebhookUrl = async (agentId: string) =>
  await shared.buildProviderWebhookUrl(AgentChannelProvider.SLACK, agentId)

export const buildSlackManifest = ({
  agent,
  messagingEndpointUrl,
  oauthRedirectUrl,

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Set both botToken (xoxb-... Slack bot token) and signingSecret in the agent's slackIntegration and save again.
  2. Check the Slack app settings: bot token from 'OAuth & Permissions', signing secret from 'Basic Information > App Credentials'.
  3. Confirm the values are non-empty after trimming - inspect for whitespace-only or undefined values in the saved agent document.
  4. If secrets come from env vars, verify they are present in the deployment environment and not empty at runtime.

Example fix

// before
agent.slackIntegration = { botToken: "xoxb-123-456-abcdef", signingSecret: "   " } // trimmed to empty
// after
agent.slackIntegration = {
  botToken: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET
}
Defensive patterns

Strategy: validation

Validate before calling

const botToken = integration.botToken?.trim()
const signingSecret = integration.signingSecret?.trim()
if (!botToken || !signingSecret) {
  throw new Error("Both botToken and signingSecret must be set (non-blank) in slackIntegration")
}

Type guard

const hasSlackCredentials = (i: { botToken?: string; signingSecret?: string }): i is { botToken: string; signingSecret: string } =>
  typeof i.botToken === "string" && i.botToken.trim() !== "" &&
  typeof i.signingSecret === "string" && i.signingSecret.trim() !== ""

Try / catch

try {
  await deployAgentToSlack(agent)
} catch (e) {
  if (e instanceof HTTPError && e.message.includes("botToken and signingSecret")) {
    // re-collect both credentials from the user
  }
  throw e
}

Prevention

When it happens

Trigger: Saving/deploying an agent whose slackIntegration contains botToken or signingSecret set to null, undefined, whitespace-only strings, or empty strings - e.g. a form that was submitted with only one of the two credentials filled in.

Common situations: User pasted the bot token but forgot the signing secret (or vice versa); environment variable interpolation produced empty strings; a partial agent update overwrote one credential with null; secrets were redacted by an export/import round-trip.

Related errors


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