{"record":{"id":"57fdc1f04b4f2454","repo":"octobercms/october","slug":"broken-json-syntax-near-key","errorCode":null,"errorMessage":"Broken JSON syntax near ${key}","messagePattern":"Broken JSON syntax near (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"modules/system/assets/js/framework.js","lineNumber":2199,"sourceCode":"        }\n        throw new Error(\"Broken JSON array near \" + result);\n      }\n    }\n    parseKey(str, pos, quote) {\n      var key = \"\";\n      for (var i = pos; i < str.length; i++) {\n        if (quote && quote === str[i]) {\n          return key;\n        } else if (!quote && (str[i] === \" \" || str[i] === \":\")) {\n          return key;\n        }\n        key += str[i];\n        if (str[i] === \"\\\\\" && i + 1 < str.length) {\n          key += str[i + 1];\n          i++;\n        }\n      }\n      throw new Error(\"Broken JSON syntax near \" + key);\n    }\n    getBody(str, pos) {\n      if (str[pos] === '\"' || str[pos] === \"'\") {\n        var body = str[pos];\n        for (var i = pos + 1; i < str.length; i++) {\n          if (str[i] === \"\\\\\") {\n            body += str[i];\n            if (i + 1 < str.length) body += str[i + 1];\n            i++;\n          } else if (str[i] === str[pos]) {\n            body += str[pos];\n            return {\n              originLength: body.length,\n              body\n            };\n          } else body += str[i];\n        }\n        throw new Error(\"Broken JSON string body near \" + body);","sourceCodeStart":2181,"sourceCodeEnd":2217,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/system/assets/js/framework.js#L2181-L2217","documentation":"Thrown by JsonParser.parseKey (October CMS AJAX framework) while scanning an object key inside the relaxed parser. Keys terminate at the closing quote, a space, or the ':' separator; if the scan consumes the whole input without any of these appearing, there is no key/value boundary and the error reports the key text accumulated so far.","triggerScenarios":"oc.parseJSON(\"{foo\") - no colon ever arrives; oc.parseJSON(\"{foo}\") - '}' is not a key terminator for an unquoted key, so the scan runs off the end; a quoted key whose closing quote is missing ({'foo: 1}).","commonSituations":"Object literals missing the colon ({foo} shorthand that the lenient parser does not accept); lost '='->':' conversions when migrating query-string syntax to JSON; missing closing quote on quoted keys; truncated attribute values ending mid-key.","solutions":["Give the key a value separator: {foo: 1} instead of {foo}","Close quoted keys properly: {'foo': 1}","If the value ends mid-key, restore the truncated tail of the attribute"],"exampleFix":"<!-- before -->\n<div data-request-data=\"{foo}\">...</div>\n\n<!-- after -->\n<div data-request-data=\"{foo: 1}\">...</div>","handlingStrategy":"try-catch","validationCode":"function keysHaveSeparators(s) {\n  const t = s.trim();\n  if (t[0] !== '{') return true;\n  // every unquoted key run must be followed by ':' before '}' or end\n  return !/\\{\\s*[\\w$]+\\s*\\}/.test(t) && !/\\{\\s*[\\w$]+\\s*$/.test(t);\n}","typeGuard":null,"tryCatchPattern":"try { const d = oc.parseJSON(raw); } catch (e) { if (/Broken JSON syntax near/.test(e.message)) console.error('Key missing its ':' separator:', e.message); }","preventionTips":["Always write key: value pairs - {foo} shorthand is not accepted","Close quoted keys with the same quote: {'foo': 1}","Watch for truncation when a value ends in the middle of a key"],"tags":["json","parser","object-keys","syntax","frontend"],"backgroundTag":"malformed-json","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}