{"record":{"id":"344d205875aeb9d2","repo":"Mintplex-Labs/anything-llm","slug":"failed-to-save-agent-flow-error-message","errorCode":null,"errorMessage":"Failed to save agent flow. ${error.message}","messagePattern":"Failed to save agent flow\\. (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/pages/Admin/AgentBuilder/index.jsx","lineNumber":220,"sourceCode":"      steps: blocks\n        .filter(\n          (block) =>\n            block.type !== BLOCK_TYPES.FINISH &&\n            block.type !== BLOCK_TYPES.FLOW_INFO\n        )\n        .map((block) => ({\n          type: block.type,\n          config: block.config,\n        })),\n    };\n\n    try {\n      const { success, error, flow } = await AgentFlows.saveFlow(\n        name,\n        flowConfig,\n        currentFlowUuid\n      );\n      if (!success) throw new Error(error);\n\n      setCurrentFlowUuid(flow.uuid);\n      showToast(\"Agent flow saved successfully!\", \"success\", { clear: true });\n      await loadAvailableFlows();\n    } catch (error) {\n      console.error(\"Save error details:\", error);\n      showToast(`Failed to save agent flow. ${error.message}`, \"error\", {\n        clear: true,\n      });\n    }\n  };\n\n  const toggleBlockExpansion = (blockId) => {\n    setBlocks(\n      blocks.map((block) =>\n        block.id === blockId\n          ? { ...block, isExpanded: !block.isExpanded }\n          : block","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/frontend/src/pages/Admin/AgentBuilder/index.jsx#L202-L238","documentation":"Thrown by the AgentBuilder save handler after AgentFlows.saveFlow(name, flowConfig, currentFlowUuid) responds with success=false, at which point the code throws new Error(error) using the server's message. It means the backend refused to persist the agent flow: blank name, invalid block type/config in the flowConfig payload, or an auth/permission problem. The toast appends the server message to 'Failed to save agent flow.'.","triggerScenarios":"Calling AgentFlows.saveFlow with an empty/undefined name, a flowConfig whose blocks array contains a type the backend schema rejects, a missing currentFlowUuid when editing an existing flow, an expired admin session (401/403 from the agent-flows endpoint), or a network/backend failure that makes the request reject.","commonSituations":"Admin leaves the flow name empty before clicking save; a custom block carries config fields the backend validator rejects; the auth token expired during a long builder session; the backend container is down or behind a 502-ing reverse proxy.","solutions":["Verify the flow has a non-empty name and at least one block before saving.","Open the browser Network tab, find the agent-flows request, and read the exact server message in the response body.","Re-login as an admin if the endpoint returned 401/403 and retry the save.","Compare each block's type and config against the backend flow schema and fix rejected fields.","Check backend server logs for the corresponding 4xx/5xx stack if the message is generic."],"exampleFix":"// before\nconst { success, error, flow } = await AgentFlows.saveFlow(name, flowConfig, currentFlowUuid);\n\n// after\nconst trimmed = (name || '').trim();\nif (!trimmed) {\n  showToast('Flow name is required before saving.', 'error', { clear: true });\n  return;\n}\nconst { success, error, flow } = await AgentFlows.saveFlow(trimmed, flowConfig, currentFlowUuid);","handlingStrategy":"validation","validationCode":"function canSaveFlow(name, blocks) {\n  const okName = typeof name === 'string' && name.trim().length > 0;\n  const okBlocks =\n    Array.isArray(blocks) &&\n    blocks.length > 0 &&\n    blocks.every((b) => b && typeof b.type === 'string' && b.config != null);\n  return okName && okBlocks;\n}\n// before AgentFlows.saveFlow:\nif (!canSaveFlow(name, flowConfig.blocks)) return showNameOrBlockError();","typeGuard":null,"tryCatchPattern":"try {\n  const { success, error, flow } = await AgentFlows.saveFlow(name, flowConfig, currentFlowUuid);\n  if (!success) throw new Error(error); // surface the server's own reason\n} catch (error) {\n  showToast(`Failed to save agent flow. ${error.message}`, 'error', { clear: true });\n}","preventionTips":["Disable the save button until the flow name is non-empty.","Keep block config forms aligned with the backend flow schema so invalid configs never reach saveFlow.","Log the full server error (console.error) alongside the toast — the server message names the rejected field."],"tags":["agent-flows","admin-ui","api-error","validation","save"],"backgroundTag":"api-validation-failed","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}