{"record":{"id":"8a9a015273e9b8ac","repo":"Budibase/budibase","slug":"operation-not-found-for-this-agent","errorCode":null,"errorMessage":"Operation not found for this agent","messagePattern":"Operation not found for this agent","errorType":"http","errorClass":"HTTPError","httpStatus":404,"severity":"error","filePath":"packages/server/src/api/controllers/ai/files.ts","lineNumber":61,"sourceCode":"  if (!path) {\n    return\n  }\n  try {\n    await unlink(path)\n  } catch (error) {\n    console.log(\"Failed to delete temp file\", error)\n  }\n}\n\nconst sanitizeSharePointSourceId = (operationId: string, siteId: string) =>\n  `sharepoint_site_${operationId.replace(/[^a-zA-Z0-9_-]/g, \"_\")}_${siteId.replace(/[^a-zA-Z0-9_-]/g, \"_\")}`\n\nconst getOperationOrThrow = (agent: Agent, operationId: string) => {\n  const operation = agent.operations?.find(\n    operation => operation.id === operationId\n  )\n  if (!operation) {\n    throw new HTTPError(\"Operation not found for this agent\", 404)\n  }\n  return operation\n}\n\nconst getSharePointSourcesForOperation = (agent: Agent, operationId: string) =>\n  (getOperationOrThrow(agent, operationId).knowledgeSources || []).filter(\n    source => source.type === AgentKnowledgeSourceType.SHAREPOINT\n  )\n\nconst allowsKnowledgeSourceDownload = (agent: Agent, operationId: string) =>\n  getOperationOrThrow(agent, operationId).allowKnowledgeSourceDownload\n\nconst fetchSharePointOptionsForDatasourceAuthConfig = async (\n  datasourceId: string,\n  authConfigId: string\n): Promise<FetchAgentKnowledgeSourceOptionsResponse> => {\n  const options = await fetchSharePointSitesByDatasourceAuthConfig(\n    datasourceId,","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/ai/files.ts#L43-L79","documentation":"getOperationOrThrow looks up an AgentOperation by id within an agent's operations array. Agents hold knowledge sources and settings per operation; when the given operationId does not match any operation on the agent, the helpers throw a 404 'Operation not found for this agent'. It is used by SharePoint source listing and the knowledge-source download permission check.","triggerScenarios":"GET/POST agent files endpoints (SharePoint sources for an operation, download-allowed check) with an operationId that is not in agent.operations — e.g. the operation was deleted, renamed/re-created with a new id, the agent record is stale, or the caller passes a knowledge-source id instead of an operation id.","commonSituations":"Client caches an operation id from before the agent was edited; agent updated in the builder while a UI tab still references the old operation; confusing operation ids with knowledge source ids or agent ids; agent document fetched from a different workspace than the operation belongs to.","solutions":["Re-fetch the agent (GET agent) and use an id from its operations array.","Verify you are passing operation.id (not knowledge source id or agent id) to the endpoint.","If the operation was deleted/recreated, redo the flow against the new operation id.","Confirm the agent document was fetched from the correct workspace/app context.","Refresh stale client caches after any agent edit in the builder."],"exampleFix":"// before\nconst opId = cachedOperationId\nawait api.get(`/api/agents/${agentId}/operations/${opId}/sharepoint/sources`)\n// after\nconst agent = (await api.get(`/api/agents/${agentId}`)).data\nconst opId = agent.operations?.[0]?.id\nif (!opId) return\nawait api.get(`/api/agents/${agentId}/operations/${opId}/sharepoint/sources`)","handlingStrategy":"type-guard","validationCode":"const op = agent.operations?.find(o => o.id === operationId)\nif (!op) throw new Error(`Operation ${operationId} not on agent ${agent._id}; refresh agent and pick a valid id`)","typeGuard":"const hasOperation = (agent: Agent, operationId: string): operationId is string =>\n  Boolean(agent.operations?.some(o => o.id === operationId))","tryCatchPattern":"try {\n  await api.get(`/api/agents/${agentId}/operations/${operationId}/sharepoint/sources`)\n} catch (e) {\n  if (e.status === 404 && e.message.includes(\"Operation not found\")) {\n    const agent = (await api.get(`/api/agents/${agentId}`)).data\n    // re-resolve operationId from agent.operations and retry once\n  }\n}","preventionTips":["Re-fetch the agent after any edit before reusing operation ids","Distinguish operation ids from knowledge-source and agent ids in client types","Invalidate cached agent/operation references when the builder updates the agent","Scope agent fetches to the correct workspace to avoid cross-app stale docs"],"tags":["http-404","not-found","ai-agents","stale-reference"],"backgroundTag":"resource-not-found","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}