Mintplex-Labs/anything-llm · error
${res.error || "Failed to save flow"}
Error message
${res.error || "Failed to save flow"} What it means
Thrown from `saveFlow` on a non-ok `POST /api/agent-flows/save`. NOTE: `res.error` is read off the fetch `Response` object, which has NO `.error` property — `res.error` is always `undefined`, so this expression ALWAYS falls through to the literal 'Failed to save flow', discarding any server-provided error message. This is a defect; compare with communityHub models that `await res.json()` first then read `response.error`.
Source
Thrown at frontend/src/models/agentFlows.js:22
const AgentFlows = {
/**
* Save a flow configuration
* @param {string} name - Display name of the flow
* @param {object} config - The configuration object for the flow
* @param {string} [uuid] - Optional UUID for updating existing flow
* @returns {Promise<{success: boolean, error: string | null, flow: {name: string, config: object, uuid: string} | null}>}
*/
saveFlow: async (name, config, uuid = null) => {
return await fetch(`${API_BASE}/agent-flows/save`, {
method: "POST",
headers: {
...baseHeaders(),
"Content-Type": "application/json",
},
body: JSON.stringify({ name, config, uuid }),
})
.then((res) => {
if (!res.ok) throw new Error(res.error || "Failed to save flow");
return res;
})
.then((res) => res.json())
.catch((e) => ({
success: false,
error: e.message,
flow: null,
}));
},
/**
* List all available flows in the system
* @returns {Promise<{success: boolean, error: string | null, flows: Array<{name: string, uuid: string, description: string, steps: Array}>}>}
*/
listFlows: async () => {
return await fetch(`${API_BASE}/agent-flows/list`, {
method: "GET",
headers: baseHeaders(),View on GitHub (pinned to 526360e320)
Solutions
- Fix the defect: parse the JSON body first, then read `response.error` (mirroring communityHub.js).
- While debugging, check the browser network tab — the response body carries the real error.
- On 401 re-authenticate; on 400 fix the payload per the server message.
- Add a test asserting the server error message propagates to the thrown Error.
Example fix
// before
.then((res) => {
if (!res.ok) throw new Error(res.error || 'Failed to save flow'); // res.error is always undefined
return res;
})
// after — read the JSON body so the server's error survives
.then(async (res) => {
const response = await res.json();
if (!res.ok) throw new Error(response?.error || `Failed to save flow (HTTP ${res.status})`);
return response;
}) Defensive patterns
Strategy: try-catch
Validate before calling
// The bug is in the model. Caller-side, validate inputs and inspect network:
function validateFlowPayload(name, config) {
if (typeof name !== 'string' || !name.trim()) throw new Error('Flow name is required');
if (!config || typeof config !== 'object') throw new Error('Flow config is required');
} Type guard
function isFlowPayloadValid(name, config) {
return typeof name === 'string' && name.trim().length > 0 && !!config && typeof config === 'object';
} Try / catch
const { success, error, flow } = await AgentFlows.saveFlow(name, config, uuid);
if (!success) {
// NOTE: error is the generic 'Failed to save flow' until the model bug is fixed.
// Inspect the network tab for the server's actual message.
showToast(error);
} Prevention
- Fix the model: read `response.error` from the parsed JSON body (see exampleFix).
- Validate name + config before posting.
- Add a test asserting the server error message propagates.
When it happens
Trigger: Any non-2xx from the save endpoint: invalid flow config, duplicate name/uuid, backend validation failure, 401/403, or 500. In every case the user sees only 'Failed to save flow', not the real reason.
Common situations: User saves a flow with a name collision or malformed config; session expires; backend schema changes; debugging is hard because the helpful server message is dropped.
Related errors
- ${res.error || "Failed to get flow"}
- ${res.error || "Failed to delete flow"}
- ${res.error || "Failed to toggle flow"}
- ${res.statusText || "Error fetching api keys."}
- ${res.statusText || "Error generating api key."}
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/eedc612347d5c441.
Report an issue: GitHub.