{"record":{"id":"564ab37e750266f0","repo":"FlowiseAI/Flowise","slug":"chatflowid-must-be-a-valid-array","errorCode":null,"errorMessage":"chatflowId must be a valid array","messagePattern":"chatflowId must be a valid array","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/evaluation/EvaluationRunner.ts","lineNumber":93,"sourceCode":"            EvaluationRunner.metrics.set(id, [metric])\n        }\n    }\n\n    baseURL = ''\n\n    constructor(baseURL: string) {\n        this.baseURL = baseURL\n    }\n\n    getChatflowApiKey(chatflowId: string, apiKeys: { chatflowId: string; apiKey: string }[] = []) {\n        return apiKeys.find((item) => item.chatflowId === chatflowId)?.apiKey || ''\n    }\n\n    public async runEvaluations(data: ICommonObject) {\n        const chatflowIds = JSON.parse(data.chatflowId)\n\n        if (!Array.isArray(chatflowIds)) {\n            throw new Error('chatflowId must be a valid array')\n        }\n\n        if (!data.dataset || !Array.isArray(data.dataset.rows)) {\n            throw new Error('dataset.rows must be a valid array')\n        }\n\n        const returnData: ICommonObject = {}\n        returnData.evaluationId = data.evaluationId\n        returnData.runDate = new Date()\n        returnData.rows = []\n        for (let i = 0; i < data.dataset.rows.length; i++) {\n            returnData.rows.push({\n                input: data.dataset.rows[i].input,\n                expectedOutput: data.dataset.rows[i].output,\n                itemNo: data.dataset.rows[i].sequenceNo,\n                evaluations: [],\n                status: 'pending'\n            })","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/evaluation/EvaluationRunner.ts#L75-L111","documentation":"EvaluationRunner.runEvaluations parses data.chatflowId via JSON.parse and requires the result to be an array. The error is thrown when the parsed value is not an Array (e.g. a plain string, number, or object), meaning the caller did not supply a JSON-serialized array of chatflow IDs. This is a request-shape validation guard before the evaluation loop iterates over chatflowIds.","triggerScenarios":"Calling runEvaluations({ chatflowId: 'abc123' }) (a bare id string), or chatflowId set to a JSON object like '{\"id\":1}', or an already-unwrapped non-JSON value. Also triggers if chatflowId is undefined, because JSON.parse(undefined) throws SyntaxError before reaching the isArray check (different message, but related misuse).","commonSituations":"Frontend sending a single selected chatflow id instead of JSON.stringify([id]); API client forgetting to serialize the array; CSV/import tooling passing raw identifiers; mismatch between API docs (which expect a JSON array string) and caller implementation.","solutions":["Serialize the chatflow IDs before calling: data.chatflowId = JSON.stringify(['flow-1','flow-2']).","If only one chatflow is evaluated, still wrap it: JSON.stringify([singleId]).","Validate the shape on the caller side with Array.isArray(JSON.parse(...)) before invoking runEvaluations.","Update the API/UI layer to always emit a JSON array string for the chatflowId field."],"exampleFix":"// before\ndata.chatflowId = selectedChatflowId // 'abc123'\n\n// after\ndata.chatflowId = JSON.stringify([selectedChatflowId]) // '[\"abc123\"]'","handlingStrategy":"validation","validationCode":"function normalizeChatflowIds(raw) {\n  let parsed\n  try { parsed = typeof raw === 'string' ? JSON.parse(raw) : raw } catch { parsed = null }\n  if (!Array.isArray(parsed) || parsed.length === 0) {\n    throw new Error('chatflowId must be a JSON-serialized non-empty array, e.g. JSON.stringify([\"flow-1\"])')\n  }\n  return JSON.stringify(parsed)\n}\n// before calling runEvaluations:\ndata.chatflowId = normalizeChatflowIds(data.chatflowId)","typeGuard":"function isChatflowIdArray(value) {\n  try {\n    const p = typeof value === 'string' ? JSON.parse(value) : value\n    return Array.isArray(p) && p.every((x) => typeof x === 'string')\n  } catch { return false }\n}","tryCatchPattern":"try {\n  await runner.runEvaluations(data)\n} catch (e) {\n  if (e.message === 'chatflowId must be a valid array') {\n    // fix data.chatflowId to JSON.stringify([...]) and retry\n  } else throw e\n}","preventionTips":["Always serialize chatflow ids with JSON.stringify at the API/UI boundary.","Document the chatflowId field as a JSON array string in your API contract.","Add an integration test that posts a single-id array to catch regressions."],"tags":["validation","evaluation","json-parse","api-contract"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}