Budibase/budibase · error · HTTPError

Slack app configuration requires a development workspace

Error message

Slack app configuration requires a development workspace

What it means

Slack app configuration is stored inside the dev workspace's database. getWorkspaceDB reads the workspace id from the request context and throws this 400 HTTPError when there is no workspace id in context or the workspace is not a development workspace (prod apps/published workspaces cannot hold Slack app config).

Source

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

  HTTPError,
} from "@budibase/backend-core"
import {
  DocumentType,
  PASSWORD_REPLACEMENT,
  SEPARATOR,
  type SlackAppConfig,
} from "@budibase/types"
import { rotateSlackConfigToken } from "./deployments/slack"

const SECRET_ENCODING_PREFIX = "bbai_enc::"
const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000

const SLACK_APP_CONFIG_ID = `${DocumentType.SLACK_APP_CONFIG}${SEPARATOR}config`

const getWorkspaceDB = () => {
  const workspaceId = context.getWorkspaceId()
  if (!workspaceId || !dbCore.isDevWorkspaceID(workspaceId)) {
    throw new HTTPError(
      "Slack app configuration requires a development workspace",
      400
    )
  }
  return context.getWorkspaceDB()
}

const encodeSecret = (value: string): string => {
  if (!value || value.startsWith(SECRET_ENCODING_PREFIX)) {
    return value
  }
  return `${SECRET_ENCODING_PREFIX}${encryption.encrypt(value)}`
}

const decodeSecret = (value: string): string => {
  if (!value || !value.startsWith(SECRET_ENCODING_PREFIX)) {
    return value
  }

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Invoke the Slack config APIs within a development workspace context (open the app in the builder / use the dev app id)
  2. Pass the correct dev workspace (appId) header/param in the request
  3. Do not manage Slack app config on published/prod apps — configure it in the dev app and deploy
  4. If running in a script/job, set the workspace context explicitly before calling (context.doInWorkspace)

Example fix

// before
await slackAppConfig.save(token, refreshToken) // no workspace context
// after
await context.doInWorkspace(devWorkspaceId, async () =>
  slackAppConfig.save(token, refreshToken)
)
Defensive patterns

Strategy: validation

Validate before calling

import { context, db as dbCore } from "@budibase/backend-core"
const workspaceId = context.getWorkspaceId()
if (!workspaceId || !dbCore.isDevWorkspaceID(workspaceId)) {
  throw new Error("Slack app config APIs require a dev workspace context")
}

Type guard

const isInDevWorkspace = (): boolean => {
  const id = context.getWorkspaceId()
  return !!id && dbCore.isDevWorkspaceID(id)
}

Try / catch

try {
  await slackAppConfig.fetch()
} catch (err) {
  if (err instanceof HTTPError && err.status === 400 && err.message.includes("development workspace")) {
    // redirect to dev workspace / set workspace context
  } else { throw err }
}

Prevention

When it happens

Trigger: Calling any Slack app config operation (fetch, save, fetchConfigToken, remove) from a context without a workspace id, or while targeting a published/production workspace instead of a dev one.

Common situations: Calling the API outside an app workspace context (e.g. from a global endpoint or script); operating on a published app instead of the dev copy; missing workspace header/route param so context is empty; automation or job running without workspace context.

Related errors


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