{"record":{"id":"2cbdedbea07635cb","repo":"stanfordnlp/CoreNLP","slug":"badly-formed-json-string-json","errorCode":null,"errorMessage":"Badly formed JSON string: ${json}","messagePattern":"Badly formed JSON string: (.+?)","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/time/suservlet/prototype.js","lineNumber":499,"sourceCode":"  },\n\n  unfilterJSON: function(filter) {\n    return this.sub(filter || Prototype.JSONFilter, '#{1}');\n  },\n\n  isJSON: function() {\n    var str = this;\n    if (str.blank()) return false;\n    str = this.replace(/\\\\./g, '@').replace(/\"[^\"\\\\\\n\\r]*\"/g, '');\n    return (/^[,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t]*$/).test(str);\n  },\n\n  evalJSON: function(sanitize) {\n    var json = this.unfilterJSON();\n    try {\n      if (!sanitize || json.isJSON()) return eval('(' + json + ')');\n    } catch (e) { }\n    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());\n  },\n\n  include: function(pattern) {\n    return this.indexOf(pattern) > -1;\n  },\n\n  startsWith: function(pattern) {\n    return this.indexOf(pattern) === 0;\n  },\n\n  endsWith: function(pattern) {\n    var d = this.length - pattern.length;\n    return d >= 0 && this.lastIndexOf(pattern) === d;\n  },\n\n  empty: function() {\n    return this == '';\n  },","sourceCodeStart":481,"sourceCodeEnd":517,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/time/suservlet/prototype.js#L481-L517","documentation":"This is a JavaScript (Prototype-style String extension) JSON parser helper. evalJSON() strips any JSON filter wrapper, optionally validates with isJSON(), and evaluates the string. If evaluation throws (or sanitization check fails), it rethrows a SyntaxError with an inspected version of the offending string, meaning the input was not parseable as JSON.","triggerScenarios":"Calling '...'.evalJSON() (optionally with sanitize=true) on a string that is not valid JSON — e.g. trailing commas, single quotes, unquoted keys, HTML instead of JSON, or a truncated response. With sanitize=true it also throws when json.isJSON() returns false.","commonSituations":"Parsing XHR/AJAX response bodies that are actually HTML error pages, empty strings, or JSONP wrappers; server returning non-JSON on error statuses; hand-built JSON strings with syntax mistakes.","solutions":["Log this.inspect() / the raw string to see what was actually received before parsing","Validate the string with .isJSON() or JSON.parse in a try block before calling evalJSON","Check the HTTP status and content-type before parsing; handle error pages separately","Use JSON.parse instead of eval-based evalJSON for safer, clearer errors"],"exampleFix":"// before\nvar data = xhr.responseText.evalJSON(true);\n// after\nvar data;\ntry { data = xhr.responseText.evalJSON(true); }\ncatch (e) { console.warn('Non-JSON response:', xhr.responseText); data = null; }","handlingStrategy":"try-catch","validationCode":"function safeEvalJSON(str) { return (str && str.isJSON && str.isJSON()) ? str.evalJSON() : null; }","typeGuard":"function looksLikeJSON(s) { return typeof s === 'string' && s.trim().charAt(0) !== '<' && s.isJSON(); }","tryCatchPattern":"try { data = responseText.evalJSON(true); } catch (e) { if (e instanceof SyntaxError) { log(responseText); data = fallbackValue; } else { throw e; } }","preventionTips":["Always check HTTP status and content-type before parsing the body","Wrap evalJSON in try/catch and log the raw string on failure","Prefer JSON.parse over eval-based parsing for safety","Sanitize/validate with isJSON() when input origin is untrusted"],"tags":["javascript","json","syntax-error"],"backgroundTag":"json-parse-error","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}