{"record":{"id":"4fc05722b02b960f","repo":"octobercms/october","slug":"broken-json-number-body-near-body-4fc057","errorCode":null,"errorMessage":"Broken JSON number body near ${body}","messagePattern":"Broken JSON number body near (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"modules/system/assets/js/framework.js","lineNumber":2258,"sourceCode":"            originLength: \"null\".length,\n            body: \"null\"\n          };\n        }\n        throw new Error(\"Broken JSON boolean body near \" + str.substr(0, pos + 10));\n      }\n      if (str[pos] === \"-\" || str[pos] === \"+\" || str[pos] === \".\" || str[pos] >= \"0\" && str[pos] <= \"9\") {\n        var body = \"\";\n        for (var i = pos; i < str.length; i++) {\n          if (str[i] === \"-\" || str[i] === \"+\" || str[i] === \".\" || str[i] >= \"0\" && str[i] <= \"9\") {\n            body += str[i];\n          } else {\n            return {\n              originLength: body.length,\n              body\n            };\n          }\n        }\n        throw new Error(\"Broken JSON number body near \" + body);\n      }\n      if (str[pos] === \"{\" || str[pos] === \"[\") {\n        var stack = [str[pos]];\n        var body = str[pos];\n        for (var i = pos + 1; i < str.length; i++) {\n          body += str[i];\n          if (str[i] === \"\\\\\") {\n            if (i + 1 < str.length) body += str[i + 1];\n            i++;\n          } else if (str[i] === '\"') {\n            if (stack[stack.length - 1] === '\"') {\n              stack.pop();\n            } else if (stack[stack.length - 1] !== \"'\") {\n              stack.push(str[i]);\n            }\n          } else if (str[i] === \"'\") {\n            if (stack[stack.length - 1] === \"'\") {\n              stack.pop();","sourceCodeStart":2240,"sourceCodeEnd":2276,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/system/assets/js/framework.js#L2240-L2276","documentation":"The number branch of getBody() in the lenient JSON scanner: it collects characters from the set [0-9 + - .] and only returns when it reaches a character outside that set. If the input ends while the scan is still inside the number — no closing brace, quote, comma or whitespace terminates it — the loop falls off the end of the string and throws with the digits collected so far. Because the surrounding object parser also relies on a terminator, a shorthand attribute whose LAST value is a bare number and whose closing brace is missing will always hit this.","triggerScenarios":"data-request-data=\"id: 5, page: 2\" — paramToObj wraps it as {id: 5, page: 2}, the final '2' runs to end-of-input and throws; data-request-data=\"{id: 25\" (explicit opening brace, missing close); oc.parseJSON('[1, 2').","commonSituations":"Using the convenient shorthand form (key: value without braces) where the last value is numeric — the wrapper only adds '{' and '}', but the trailing '}' is what the number scanner needs as terminator, so any omission truncates the number; partials rendered dynamically where the closing '}' gets dropped by templating or escaping.","solutions":["Add the closing brace so the number is terminated: use the fully braced form data-request-data=\"{id: 5, page: 2}\".","Check the reported 'near <body>' digits against your attribute to confirm which value ran to the end.","If the brace is present in source but missing at runtime, inspect the rendered HTML — a stray quote or templating bug is truncating the attribute."],"exampleFix":"// before — last value runs to end of input\n<a data-request=\"onPaginate\" data-request-data=\"id: 5, page: 2\">Next</a>\n\n// after\n<a data-request=\"onPaginate\" data-request-data=\"{id: 5, page: 2}\">Next</a>","handlingStrategy":"validation","validationCode":"// Shorthand values whose last value is numeric MUST carry their own closing brace\nfunction needsClosingBrace(value) {\n    var v = value.trim();\n    return v.charAt(0) !== '{' && /[0-9.\\-+]\\s*$/.test(v);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always author data-request-data in the explicit braced form {k: v, k2: v2}.","End attribute object values with the closing brace — the number scanner needs a terminator.","In templates, assert generated attribute values start with '{' and end with '}'."],"tags":["json","parsing","frontend","data-attribute","number-literal"],"backgroundTag":"truncated-json","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}