{"record":{"id":"097663bb95058501","repo":"Budibase/budibase","slug":"escalation-gate-missing-workspace-context","errorCode":null,"errorMessage":"escalation gate: missing workspace context","messagePattern":"escalation gate: missing workspace context","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/server/src/sdk/workspace/ai/agents/escalationGate.ts","lineNumber":116,"sourceCode":"    const rule = matchRule(rules)\n    if (!rule) {\n      return unavailableResult(label)\n    }\n\n    const policy = resolvePolicy(operation, rule.policyId)\n    const notifications: AgentEscalationConfig | undefined =\n      policy?.notifications\n    if (!policy || !notifications?.recipients?.length) {\n      return unavailableResult(label)\n    }\n\n    const frozenMessages = messages?.length\n      ? messages\n      : gateContext.getMessages()\n    const appId = context.getWorkspaceId()\n    const tenantId = context.getTenantId()\n    if (!appId) {\n      throw new Error(\"escalation gate: missing workspace context\")\n    }\n\n    let title = `Approval required: ${label}`\n    let summary = summariseArgs(label, input)\n    try {\n      const copy = await gateContext.generateCardCopy?.({\n        label,\n        args: input,\n      })\n      if (copy?.title && copy?.summary) {\n        title = copy.title\n        summary = copy.summary\n      }\n    } catch (error) {\n      console.warn(\"escalation gate: card copy generation failed\", {\n        toolName,\n        error: error instanceof Error ? error.message : String(error),\n      })","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/ai/agents/escalationGate.ts#L98-L134","documentation":"The escalation gate runtime needs to know which workspace (app) the escalation approval card belongs to. It reads the workspace ID from the ambient request context; when the context has no workspace ID it cannot scope the approval, so it throws a plain Error before building the card. This is an internal invariant failure: the SDK is being used outside a properly established workspace context.","triggerScenarios":"Calling createEscalationGateRuntime (e.g. during an agent run that hits an escalation-enabled operation) when context.getWorkspaceId() returns undefined - typically when the agent is invoked outside an HTTP request scoped to an app, or in a job/test with no workspace context installed.","commonSituations":"Running agent escalations from background scripts, automation triggers, or tests without wrapping the call in a workspace context; calling the SDK directly rather than through the server API routes that install the context.","solutions":["Ensure the escalation gate is invoked within a request/job that has a workspace context set (context.withContext / the server API routes).","Verify the agent run path passes the app ID so getWorkspaceId() resolves; do not call the SDK raw in worker jobs without context.","If writing tests, set up a workspace context middleware/helper before calling the gate runtime."],"exampleFix":"// before\nawait gateRuntime.run(...) // called outside any workspace context\n// after\nawait context.doInWorkspaceContext(appId, async () => {\n  await gateRuntime.run(...)\n})","handlingStrategy":"validation","validationCode":"import context from \"@budibase/backend-core/context\"\nconst canRun = () => !!context.getWorkspaceId()\nif (!canRun()) throw new Error(\"Call must run inside a workspace context\")","typeGuard":"const hasWorkspaceContext = (): boolean =>\n  typeof context.getWorkspaceId() === \"string\" && context.getWorkspaceId().length > 0","tryCatchPattern":"try {\n  await gateRuntime.run(...)\n} catch (err) {\n  if ((err as Error).message === \"escalation gate: missing workspace context\") {\n    // re-invoke inside a workspace context or fail the run with a clear message\n  }\n}","preventionTips":["Only invoke agent SDK runtimes from request/job handlers that install workspace context.","Add a startup assertion in scripts/tests that a workspace context wrapper is used.","Never call gate runtimes at module top-level."],"tags":["context","agents","server"],"backgroundTag":"missing-workspace-context","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}