{"record":{"id":"eedfa1992eb446d7","repo":"FlowiseAI/Flowise","slug":"values-must-be-a-valid-json-array","errorCode":null,"errorMessage":"Values must be a valid JSON array","messagePattern":"Values must be a valid JSON array","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/tools/GoogleSheets/core.ts","lineNumber":390,"sourceCode":"            method: 'PUT',\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 values\n            try {\n                values = JSON.parse(params.values)\n            } catch (error) {\n                throw new Error('Values must be a valid JSON array')\n            }\n\n            const body = {\n                values,\n                majorDimension: params.majorDimension || 'ROWS'\n            }\n\n            const queryParams = new URLSearchParams()\n            queryParams.append('valueInputOption', params.valueInputOption || 'USER_ENTERED')\n\n            const encodedRange = encodeURIComponent(params.range)\n            const endpoint = `spreadsheets/${params.spreadsheetId}/values/${encodedRange}?${queryParams.toString()}`\n\n            return await this.makeGoogleSheetsRequest({\n                endpoint,\n                method: 'PUT',\n                body,\n                params","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/tools/GoogleSheets/core.ts#L372-L408","documentation":"Thrown inside UpdateValuesTool._call when JSON.parse(params.values) throws. The UpdateValuesSchema declares values as a string that must itself be valid JSON (e.g. \"[[\\\"A1\\\",\\\"B1\\\"]]\"), because the tool serializes the parsed array into the Google Sheets values body. The inner try/catch converts any parse failure — SyntaxError from a trailing comma, unquoted key, or a raw non-JSON string — into this fixed message, discarding the original parse error.","triggerScenarios":"An LLM agent supplies params.values as a bare array literal \"[[a,b]]\" without quotes, as a comma-separated list \"a,b,c\", as a JS object \"{values:[[1]]}\", or with smart-quotes/special whitespace. Also triggered when defaultParams.values and arg.values merge into a doubled/corrupted string, or when an upstream node emits the array as \"[object Array]\".","commonSituations":"Agent models that emit CSV instead of JSON; a previous node passes a stringified array that gets stringified again (double-encoded \"\\\\\\\"[[1]]\\\\\\\"\"); copy-paste from a spreadsheet cell that contains a leading apostrophe; locale decimal separators (1,5) leaking into the JSON.","solutions":["Pre-stringify the array exactly once before assigning to values: values: JSON.stringify([[\"A1\",\"B1\"]]).","Validate with JSON.parse in a guard before invoking the tool so you get the real parse error position.","If the source is an agent, tighten the schema description or add a few-shot example showing the double-bracket string shape.","Confirm defaultParams.values is not simultaneously set to a different shape than arg.values (the spread { ...arg, ...this.defaultParams } lets defaults clobber a good arg)."],"exampleFix":"// before — values is a CSV-like string, parse fails\nconst res = await updateValues.invoke({ spreadsheetId, range: 'A1:B1', values: 'a,b' })\n// after — values is a JSON-stringified 2D array\nconst res = await updateValues.invoke({ spreadsheetId, range: 'A1:B1', values: JSON.stringify([['a','b']]) })","handlingStrategy":"validation","validationCode":"function asValues2D(input: unknown): string {\n  // accept array, JSON string of array, or fail fast with a clear error\n  let arr: unknown\n  if (typeof input === 'string') {\n    arr = JSON.parse(input) // throws precise error if bad\n  } else {\n    arr = input\n  }\n  if (!Array.isArray(arr) || !arr.every(r => Array.isArray(r))) {\n    throw new Error('values must be a 2D array (string[][]), got: ' + JSON.stringify(arr).slice(0,120))\n  }\n  return JSON.stringify(arr)\n}\n// then: values: asValues2D(raw)","typeGuard":"function is2DStringArray(v: unknown): v is string[][] {\n  return Array.isArray(v) && v.every(r => Array.isArray(r) && r.every(c => typeof c === 'string'))\n}","tryCatchPattern":"try {\n  return await updateValues.invoke({ ..., values: asValues2D(raw) })\n} catch (e) {\n  if (e instanceof Error && e.message === 'Values must be a valid JSON array') {\n    return { error: 'malformed values', raw } // feed back to agent\n  }\n  throw e\n}","preventionTips":["Always JSON.stringify the 2D array exactly once before passing it as values.","Strip dynamic cell content of control characters and unescaped quotes.","In agent prompts, show the literal shape [[\"A1\",\"B1\"]] as a few-shot example.","Assert defaultParams.values and arg.values aren't both set to incompatible shapes."],"tags":["google-sheets","json-parse","validation","agent-input"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}