Mintplex-Labs/anything-llm · error · Error

Failed to save agent flow. ${error.message}

Error message

Failed to save agent flow. ${error.message}

What it means

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.'.

Source

Thrown at frontend/src/pages/Admin/AgentBuilder/index.jsx:220

      steps: blocks
        .filter(
          (block) =>
            block.type !== BLOCK_TYPES.FINISH &&
            block.type !== BLOCK_TYPES.FLOW_INFO
        )
        .map((block) => ({
          type: block.type,
          config: block.config,
        })),
    };

    try {
      const { success, error, flow } = await AgentFlows.saveFlow(
        name,
        flowConfig,
        currentFlowUuid
      );
      if (!success) throw new Error(error);

      setCurrentFlowUuid(flow.uuid);
      showToast("Agent flow saved successfully!", "success", { clear: true });
      await loadAvailableFlows();
    } catch (error) {
      console.error("Save error details:", error);
      showToast(`Failed to save agent flow. ${error.message}`, "error", {
        clear: true,
      });
    }
  };

  const toggleBlockExpansion = (blockId) => {
    setBlocks(
      blocks.map((block) =>
        block.id === blockId
          ? { ...block, isExpanded: !block.isExpanded }
          : block

View on GitHub (pinned to 3aec848f28)

Solutions

  1. Verify the flow has a non-empty name and at least one block before saving.
  2. Open the browser Network tab, find the agent-flows request, and read the exact server message in the response body.
  3. Re-login as an admin if the endpoint returned 401/403 and retry the save.
  4. Compare each block's type and config against the backend flow schema and fix rejected fields.
  5. Check backend server logs for the corresponding 4xx/5xx stack if the message is generic.

Example fix

// before
const { success, error, flow } = await AgentFlows.saveFlow(name, flowConfig, currentFlowUuid);

// after
const trimmed = (name || '').trim();
if (!trimmed) {
  showToast('Flow name is required before saving.', 'error', { clear: true });
  return;
}
const { success, error, flow } = await AgentFlows.saveFlow(trimmed, flowConfig, currentFlowUuid);
Defensive patterns

Strategy: validation

Validate before calling

function canSaveFlow(name, blocks) {
  const okName = typeof name === 'string' && name.trim().length > 0;
  const okBlocks =
    Array.isArray(blocks) &&
    blocks.length > 0 &&
    blocks.every((b) => b && typeof b.type === 'string' && b.config != null);
  return okName && okBlocks;
}
// before AgentFlows.saveFlow:
if (!canSaveFlow(name, flowConfig.blocks)) return showNameOrBlockError();

Try / catch

try {
  const { success, error, flow } = await AgentFlows.saveFlow(name, flowConfig, currentFlowUuid);
  if (!success) throw new Error(error); // surface the server's own reason
} catch (error) {
  showToast(`Failed to save agent flow. ${error.message}`, 'error', { clear: true });
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18). Data as JSON: /api/errors/344d205875aeb9d2. Report an issue: GitHub.