FlowiseAI/Flowise · error · Error

dataset.rows must be a valid array

Error message

dataset.rows must be a valid array

What it means

EvaluationRunner.runEvaluations requires data.dataset to exist and data.dataset.rows to be an Array. It guards the subsequent loop that indexes data.dataset.rows[i].input/output/sequenceNo. Thrown when the dataset payload is missing, not an object, or its rows field is absent/non-array.

Source

Thrown at packages/components/evaluation/EvaluationRunner.ts:97

    baseURL = ''

    constructor(baseURL: string) {
        this.baseURL = baseURL
    }

    getChatflowApiKey(chatflowId: string, apiKeys: { chatflowId: string; apiKey: string }[] = []) {
        return apiKeys.find((item) => item.chatflowId === chatflowId)?.apiKey || ''
    }

    public async runEvaluations(data: ICommonObject) {
        const chatflowIds = JSON.parse(data.chatflowId)

        if (!Array.isArray(chatflowIds)) {
            throw new Error('chatflowId must be a valid array')
        }

        if (!data.dataset || !Array.isArray(data.dataset.rows)) {
            throw new Error('dataset.rows must be a valid array')
        }

        const returnData: ICommonObject = {}
        returnData.evaluationId = data.evaluationId
        returnData.runDate = new Date()
        returnData.rows = []
        for (let i = 0; i < data.dataset.rows.length; i++) {
            returnData.rows.push({
                input: data.dataset.rows[i].input,
                expectedOutput: data.dataset.rows[i].output,
                itemNo: data.dataset.rows[i].sequenceNo,
                evaluations: [],
                status: 'pending'
            })
        }
        for (let i = 0; i < chatflowIds.length; i++) {
            const chatflowId = chatflowIds[i]
            await this.evaluateChatflow(chatflowId, this.getChatflowApiKey(chatflowId, data.apiKeys), data, returnData)

View on GitHub (pinned to abe4a8601a)

Solutions

  1. Ensure the payload includes dataset.rows as an array, e.g. data.dataset = { rows: [{ input, output, sequenceNo }, ...] }.
  2. Verify the dataset upload/import pipeline returns an array before assigning it to data.dataset.rows.
  3. Add a caller-side guard: if (!data?.dataset?.rows?.length) throw a clearer upstream error.
  4. Check that the HTTP request body was not truncated/clipped by a proxy or body-size limit.

Example fix

// before
data.dataset = { columns: ['input','output'] } // no rows

// after
data.dataset = {
  rows: datasetRows.map(r => ({ input: r.input, output: r.output, sequenceNo: r.sequenceNo }))
}
Defensive patterns

Strategy: validation

Validate before calling

function validateDataset(data) {
  if (!data?.dataset || !Array.isArray(data.dataset.rows) || data.dataset.rows.length === 0) {
    throw new Error('data.dataset.rows must be a non-empty array of { input, output, sequenceNo }')
  }
  return data.dataset.rows
}
const rows = validateDataset(data)

Type guard

function isDatasetRows(value) {
  return !!value?.dataset && Array.isArray(value.dataset.rows)
}

Try / catch

try {
  await runner.runEvaluations(data)
} catch (e) {
  if (e.message.startsWith('dataset.rows')) {
    // rebuild data.dataset.rows from the source dataset and retry
  } else throw e
}

Prevention

When it happens

Trigger: Calling runEvaluations without a dataset field; passing dataset as null; passing dataset.rows as an object/CSV string instead of an array; uploading a dataset whose parser returned undefined; partial payload from a truncated request body.

Common situations: Dataset upload step skipped or failed silently; UI sending { dataset: { columns: [...] } } but omitting rows; backend deserializer mapping rows to a different key; testing with a stubbed empty payload.

Related errors


AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12). Data as JSON: /api/errors/ddea06430fa74e5f. Report an issue: GitHub.