{"record":{"id":"73fed522645b5691","repo":"FlowiseAI/Flowise","slug":"invalid-json-string-error-instanceof-error-er","errorCode":null,"errorMessage":"Invalid JSON string: ${error instanceof Error ? error.message : 'Parse error'}","messagePattern":"Invalid JSON string: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/tools/JSONPathExtractor/JSONPathExtractor.ts","lineNumber":48,"sourceCode":"        // Validate that path is configured\n        if (!this.path) {\n            if (this.returnNullOnError) {\n                return 'null'\n            }\n            throw new Error('No extraction path configured')\n        }\n\n        let data: any\n\n        // Parse JSON string if needed\n        if (typeof json === 'string') {\n            try {\n                data = JSON.parse(json)\n            } catch (error) {\n                if (this.returnNullOnError) {\n                    return 'null'\n                }\n                throw new Error(`Invalid JSON string: ${error instanceof Error ? error.message : 'Parse error'}`)\n            }\n        } else {\n            data = json\n        }\n\n        // Extract value using lodash get\n        const value = get(data, this.path)\n\n        if (value === undefined) {\n            if (this.returnNullOnError) {\n                return 'null'\n            }\n            const jsonPreview = JSON.stringify(data, null, 2)\n            const preview = jsonPreview.length > 200 ? jsonPreview.substring(0, 200) + '...' : jsonPreview\n            throw new Error(`Path \"${this.path}\" not found in JSON. Received: ${preview}`)\n        }\n\n        return typeof value === 'string' ? value : JSON.stringify(value)","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/tools/JSONPathExtractor/JSONPathExtractor.ts#L30-L66","documentation":"Thrown by JSONPathExtractorTool._call when the json argument is a string that fails JSON.parse, with returnNullOnError disabled. The schema accepts string | object | array; objects/arrays skip parsing, but strings are assumed to be serialized JSON. The original parse error message (e.g. 'Unexpected token ... in JSON at position N') is appended so the caller can locate the malformed byte.","triggerScenarios":"An upstream node emits prettified JSON with trailing comments, a JS object literal (unquoted keys), a Markdown-fenced ```json block, or text that merely resembles JSON. Also when a stringified value is double-decoded or when the LLM wraps the JSON in prose.","commonSituations":"LLM output piped directly into the extractor without stripping reasoning text; CSV/YAML fed where JSON was expected; copy-paste introducing smart quotes; a previous extractor step that already returned an object but the wiring typed it as string.","solutions":["Strip code fences and surrounding prose from the input before invoking: json.replace(/```json|```/g,'').trim().","If the source might be non-JSON, enable returnNullOnError to degrade gracefully.","Validate upstream with a JSON.parse guard and surface the position to fix the emitter.","If the data is already an object, pass it as an object (the schema allows it) instead of re-stringifying."],"exampleFix":"// before\nawait extractor.invoke({ json: 'Here is the data: {\"a\":1}' })\n// after\nconst clean = raw.replace(/^[^{[]*/, '').trim()\nawait extractor.invoke({ json: clean })","handlingStrategy":"type-guard","validationCode":"function asJsonInput(json: unknown): any {\n  if (typeof json !== 'string') return json // already object/array\n  const trimmed = json.replace(/```json|```/g, '').trim()\n  try {\n    return JSON.parse(trimmed)\n  } catch (e) {\n    throw new Error(`input is not valid JSON: ${(e as Error).message}`)\n  }\n}","typeGuard":"function isParsableJson(s: unknown): s is string {\n  if (typeof s !== 'string') return false\n  try { JSON.parse(s.replace(/```json|```/g,'').trim()); return true } catch { return false }\n}","tryCatchPattern":"try {\n  return await extractor.invoke({ json: asJsonInput(raw) })\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Invalid JSON string:')) {\n    // strip prose/fences and retry, or enable returnNullOnError\n  }\n  throw e\n}","preventionTips":["Strip Markdown code fences and surrounding prose from LLM output before extracting.","Pass objects directly (the schema allows it) instead of re-stringifying.","Enable returnNullOnError when the input source is untrusted.","Validate upstream with JSON.parse to catch the position of the malformed byte."],"tags":["jsonpath","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"}