Budibase/budibase · error · HTTPError

Operation not found for this agent

Error message

Operation not found for this agent

What it means

getOperationOrThrow looks up an agent operation by ID within an agent's operations array. If no operation on the agent matches the given operationId, it throws a 404 HTTPError. This guards updateOperation and removeOperation against mutating a non-existent operation.

Source

Thrown at packages/server/src/sdk/workspace/ai/agents/operations.ts:27

  | "promptInstructions"
  | "enabledTools"
  | "approvalPolicies"
  | "allowKnowledgeSourceDownload"
  | "escalation"
>

export type CreateAgentOperationInput = AgentOperationConfig &
  Pick<AgentOperation, "id">

const normalizeOperationName = (name: string | undefined) =>
  name?.trim().toLowerCase() || ""

const getOperationOrThrow = (agent: Agent, operationId: string) => {
  const operation = agent.operations?.find(
    candidate => candidate.id === operationId
  )
  if (!operation) {
    throw new HTTPError("Operation not found for this agent", 404)
  }
  return operation
}

const mergeOperationConfig = (
  existing: AgentOperation,
  incoming: Partial<AgentOperationConfig>
): AgentOperation => ({
  ...existing,
  ...incoming,
  id: existing.id,
  knowledgeBases: existing.knowledgeBases,
  knowledgeSources: existing.knowledgeSources,
  escalation: incoming.escalation ?? existing.escalation,
})

const assertUniqueOperationName = (
  agent: Agent,

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Fetch the agent and confirm the operationId exists in agent.operations before calling update/remove.
  2. Refresh the agent document to get current operation IDs if the client may hold stale data.
  3. Handle the 404 HTTPError in the API layer and surface 'operation not found' to the caller.

Example fix

// before
await updateOperation(agentId, someStaleId, config) // 404
// after
const agent = await getOrThrow(agentId)
if (!agent.operations?.some(o => o.id === someStaleId)) {
  throw new HTTPError("Operation not found for this agent", 404)
}
await updateOperation(agentId, someStaleId, config)
Defensive patterns

Strategy: type-guard

Validate before calling

const op = agent.operations?.find(o => o.id === operationId)
if (!op) throw new HTTPError("Operation not found", 404)
// only then call updateOperation/removeOperation

Type guard

const hasOperation = (agent: Agent, operationId: string): boolean =>
  !!agent.operations?.some(o => o.id === operationId)

Try / catch

try {
  await removeOperation(agentId, operationId)
} catch (err) {
  if (err instanceof HTTPError && err.status === 404) {
    // treat as already-deleted / stale client data
  }
}

Prevention

When it happens

Trigger: Calling updateOperation(agentId, operationId, ...) or removeOperation(agentId, operationId) with an operationId that does not exist on the agent (deleted already, wrong agent, typo'd/stale ID from a client).

Common situations: Client UI holding a stale operation ID after the operation was removed; calling with an ID from a different agent; concurrent edits where one session deletes the operation another is editing.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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