{"record":{"id":"c6c2f287ce6f18ad","repo":"FlowiseAI/Flowise","slug":"values-must-be-a-valid-json-array-of-value-ranges","errorCode":null,"errorMessage":"Values must be a valid JSON array of value ranges","messagePattern":"Values must be a valid JSON array of value ranges","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/tools/GoogleSheets/core.ts","lineNumber":582,"sourceCode":"            method: 'POST',\n            headers: {}\n        }\n        super({\n            ...toolInput,\n            accessToken: args.accessToken\n        })\n        this.defaultParams = args.defaultParams || {}\n    }\n\n    async _call(arg: any): Promise<string> {\n        const params = { ...arg, ...this.defaultParams }\n\n        try {\n            let valueRanges\n            try {\n                valueRanges = JSON.parse(params.values)\n            } catch (error) {\n                throw new Error('Values must be a valid JSON array of value ranges')\n            }\n\n            const body = {\n                valueInputOption: params.valueInputOption || 'USER_ENTERED',\n                data: valueRanges,\n                includeValuesInResponse: params.includeValuesInResponse || false\n            }\n\n            const endpoint = `spreadsheets/${params.spreadsheetId}/values:batchUpdate`\n\n            return await this.makeGoogleSheetsRequest({\n                endpoint,\n                method: 'POST',\n                body,\n                params\n            })\n        } catch (error) {\n            return formatToolError(`Error batch updating values: ${error}`, params)","sourceCodeStart":564,"sourceCodeEnd":600,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/tools/GoogleSheets/core.ts#L564-L600","documentation":"Thrown by BatchUpdateValuesTool._call when JSON.parse(params.values) fails. Unlike update/append, BatchUpdateValuesSchema describes values as a JSON array of value-range objects ([{\"range\":\"Sheet1!A1:B2\",\"values\":[[...]]}]), and the parsed result is placed under body.data for the values:batchUpdate endpoint. A parse failure here usually means the agent modeled the input as a single range instead of an array of {range, values} objects.","triggerScenarios":"params.values is a 2D array (correct for update but wrong for batch), a single {range,values} object rather than an array of them, or a malformed multi-range JSON. The body.data field then receives a non-array, but the throw happens earlier at the parse step.","commonSituations":"Reusing an update_values prompt template for batch_update_values; agents concatenating range objects with commas without an enclosing array; trailing commas after the last element.","solutions":["Ensure values is JSON.stringify([{range:'Sheet1!A1:B2', values:[['x','y']]}, ...]) — an array of value-range objects.","Differentiate the prompt/schema from update_values: emphasize 'array of {range, values} objects'.","Validate with Array.isArray(parsed) and parsed.every(r => r.range && Array.isArray(r.values)) after parsing.","If only one range is needed, prefer update_values over batch_update_values to avoid the structural mismatch."],"exampleFix":"// before — flat 2D array, wrong for batch\nvalues: JSON.stringify([['a','b']])\n// after — array of value-range objects\nvalues: JSON.stringify([{ range: 'Sheet1!A1:B1', values: [['a','b']] }])","handlingStrategy":"validation","validationCode":"function asValueRanges(input: unknown): string {\n  const arr = typeof input === 'string' ? JSON.parse(input) : input\n  if (!Array.isArray(arr) || !arr.every(r => r && typeof r === 'object' && 'range' in r && Array.isArray((r as any).values))) {\n    throw new Error('batch values must be an array of { range, values[][] }')\n  }\n  return JSON.stringify(arr)\n}","typeGuard":"interface ValueRange { range: string; values: unknown[][] }\nfunction isValueRangeArray(v: unknown): v is ValueRange[] {\n  return Array.isArray(v) && v.every(r => !!r && typeof r === 'object' && typeof (r as any).range === 'string' && Array.isArray((r as any).values))\n}","tryCatchPattern":"try {\n  return await batchUpdate.invoke({ ..., values: asValueRanges(input) })\n} catch (e) {\n  if (e instanceof Error && e.message === 'Values must be a valid JSON array of value ranges') {\n    return wrapAsValueRanges(input) // auto-fix single range\n  }\n  throw e\n}","preventionTips":["Reuse distinct prompts for batch vs single update to avoid shape confusion.","Validate Array.isArray + every({range, values}) before the call.","For a single range, prefer update_values over batch_update_values.","Show the exact {range, values} object shape in the agent's few-shot examples."],"tags":["google-sheets","json-parse","validation","batch"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}