Budibase/budibase · error · HTTPError

workspaceId is required

Error message

workspaceId is required

What it means

This HTTP 400 error is thrown by buildWebhookUrl in packages/server/src/sdk/workspace/ai/deployments/shared.ts when there is no workspace (app) ID available in the current request context while building a provider webhook URL. The webhook URL embeds the workspace ID as a path segment, so it is mandatory. getWorkspaceId() returns undefined when the code runs outside an app/workspace context (e.g. in the platform/global context or during a job without app context).

Source

Thrown at packages/server/src/sdk/workspace/ai/deployments/shared.ts:27

/** Webhook URL path segment (ms-teams uses hyphen, provider value uses msteams) */
export const WEBHOOK_PATH_BY_PROVIDER: Record<AgentChannelProvider, string> = {
  [AgentChannelProvider.MSTEAMS]: "ms-teams",
  [AgentChannelProvider.SLACK]: "slack",
}

export const buildWebhookUrl = async ({
  provider,
  agentId,
  useProdWorkspaceId = false,
}: {
  provider: AgentChannelProvider
  agentId: string
  useProdWorkspaceId?: boolean
}) => {
  const platformUrl = await configs.getPlatformUrl({ tenantAware: true })
  const workspaceId = context.getWorkspaceId()
  if (!workspaceId) {
    throw new HTTPError("workspaceId is required", 400)
  }
  const targetWorkspaceId = useProdWorkspaceId
    ? dbCore.getProdWorkspaceID(workspaceId)
    : workspaceId
  const pathSegment = WEBHOOK_PATH_BY_PROVIDER[provider]
  return `${platformUrl.replace(/\/$/, "")}/api/webhooks/${pathSegment}/${targetWorkspaceId}/${agentId}`
}

export const buildProviderWebhookUrl = async (
  provider: AgentChannelProvider,
  agentId: string
) =>
  await buildWebhookUrl({
    provider,
    agentId,
    useProdWorkspaceId: true,
  })

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Ensure the code that builds the webhook URL runs inside a workspace context (open the app's context, e.g. tenancy/doInWorkspace or equivalent before calling).
  2. Pass the workspace/app ID through your request or job payload and set the context before invoking buildProviderWebhookUrl.
  3. If testing, wrap the call in a test context helper that sets a workspace ID before asserting.
  4. Check the deployment entry point (API route) is app-scoped, not a global/platform route.

Example fix

// before
const url = await buildProviderWebhookUrl({ provider: "slack", agentId }) // runs with no workspace context
// after
await withWorkspace(appId, async () => {
  const url = await buildProviderWebhookUrl({ provider: "slack", agentId })
})
Defensive patterns

Strategy: validation

Validate before calling

const workspaceId = context.getWorkspaceId()
if (!workspaceId) {
  throw new Error("buildProviderWebhookUrl requires an active workspace context; open the app context first")
}

Type guard

const hasWorkspace = (): workspaceId is string => typeof context.getWorkspaceId() === "string" && context.getWorkspaceId() !== ""

Try / catch

try {
  const url = await buildProviderWebhookUrl({ provider, agentId })
} catch (e) {
  if (e instanceof HTTPError && e.message === "workspaceId is required") {
    // retry inside the app's workspace context
  }
  throw e
}

Prevention

When it happens

Trigger: Calling buildProviderWebhookUrl (for Slack, MS Teams, etc.) from a context where context.getWorkspaceId() returns undefined - e.g. building a webhook URL for an agent while operating at the platform/tenant level, in a background job without app context propagated, or before an app/workspace is opened in the request lifecycle.

Common situations: Running agent deployment code in a worker or script that did not switch into the app's database context; calling the deployment API without an app id in the request; unit/integration testing the function without initialising request context.

Related errors


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