octobercms/october · error · Error

Broken JSON body near ${str}

Error message

Broken JSON body near ${str}

What it means

The fallback throw at the bottom of JsonParser.getBody in October CMS's AJAX framework: the character at the value position cannot begin any JSON value this parser knows (not a quote, not t/f/n keyword start, not a number character, not '{' or '['). The message echoes up to 50 characters starting 5 bytes before the failure point to give context.

Source

Thrown at modules/system/assets/js/framework-bundle.js:2327

              stack.push("[");
            } else if (str[i] === "]") {
              if (stack[stack.length - 1] === "[") {
                stack.pop();
              } else {
                throw new Error("Broken JSON " + (str[pos] === "{" ? "object" : "array") + " body near " + body);
              }
            }
          }
          if (!stack.length) {
            return {
              originLength: i - pos,
              body
            };
          }
        }
        throw new Error("Broken JSON " + (str[pos] === "{" ? "object" : "array") + " body near " + body);
      }
      throw new Error("Broken JSON body near " + str.substr(pos - 5 >= 0 ? pos - 5 : 0, 50));
    }
    canBeKeyHead(ch) {
      if (ch[0] === "\\") return false;
      if (ch[0] >= "a" && ch[0] <= "z" || ch[0] >= "A" && ch[0] <= "Z" || ch[0] === "_") return true;
      if (ch[0] >= "0" && ch[0] <= "9") return true;
      if (ch[0] === "$") return true;
      if (ch.charCodeAt(0) > 255) return true;
      return false;
    }
    isBlankChar(ch) {
      return ch === " " || ch === "\n" || ch === "	";
    }
  };

  // ../../vendor/larajax/larajax/resources/src/core/request-builder.js
  var RequestBuilder = class _RequestBuilder {
    constructor(element, handler, options) {
      this.options = options || {};

View on GitHub (pinned to b608633a7e)

Solutions

  1. Give the value a legal form: quote words ({fn: 'x'}), use true/false/null, a number, or {..}/[..]
  2. Remove empty value slots ({a: ,b: 1} -> {b: 1})
  3. Pre-parse the attribute with oc.parseJSON during development to catch illegal value starts before the request fires

Example fix

<!-- before -->
<div data-request-data="{fn: x, a: ,b: 1}">...</div>

<!-- after -->
<div data-request-data="{fn: 'x', b: 1}">...</div>
Defensive patterns

Strategy: validation

Validate before calling

function valuesStartLegally(s) {
  // every value position (after ':' or ',' or '[' ) must start with a legal token
  return !/[:,\[]\s*([^\s\-+.\d\{"'tfn\]}].*)?$/.test(s);
}

Try / catch

try { oc.request(el, 'onGo'); } catch (e) { if (/Broken JSON body near/.test(e.message)) console.error('Illegal value start:', e.message); }

Prevention

When it happens

Trigger: A value position starting with ',', ':', ')', '}' via a bare position, or any letter other than t/f/n - e.g. oc.parseJSON("{a: ,b: 1}") (empty value before comma) or data-request-data="{fn: x}") where x is an unquoted word that is not true/false/null.

Common situations: Empty value left between commas ({a: ,b: 1}); unquoted identifiers as values (must be quoted); a variable placeholder like {tpl: %s} not substituted; stray punctuation pasted into the attribute.

Related errors


AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21). Data as JSON: /api/errors/eb583dd3243b5b6d. Report an issue: GitHub.