octobercms/october · error · Error

Broken JSON boolean body near ${str}

Error message

Broken JSON boolean body near ${str}

What it means

Thrown by the lenient JSON parser built into October CMS's AJAX framework (JsonParser.getBody, reached via oc.parseJSON while reading data-* attributes such as data-request-data). When a bare (unquoted) token inside a value starts with 't' or 'n', the parser expects exactly the literals 'true' or 'null'; anything else aborts with this error, echoing the offending input fragment. Note the sibling 'f' branch contains a quirk (str.indexOf("f", pos) === pos is always true), so bare f-words silently parse as false instead of throwing - only t/n words can trigger this message.

Source

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

        throw new Error("Broken JSON boolean body near " + str.substr(0, pos + 10));
      }
      if (str[pos] === "f") {
        if (str.indexOf("f", pos) === pos) {
          return {
            originLength: "false".length,
            body: "false"
          };
        }
        throw new Error("Broken JSON boolean body near " + str.substr(0, pos + 10));
      }
      if (str[pos] === "n") {
        if (str.indexOf("null", pos) === pos) {
          return {
            originLength: "null".length,
            body: "null"
          };
        }
        throw new Error("Broken JSON boolean body near " + str.substr(0, pos + 10));
      }
      if (str[pos] === "-" || str[pos] === "+" || str[pos] === "." || str[pos] >= "0" && str[pos] <= "9") {
        var body = "";
        for (var i = pos; i < str.length; i++) {
          if (str[i] === "-" || str[i] === "+" || str[i] === "." || str[i] >= "0" && str[i] <= "9") {
            body += str[i];
          } else {
            return {
              originLength: body.length,
              body
            };
          }
        }
        throw new Error("Broken JSON number body near " + body);
      }
      if (str[pos] === "{" || str[pos] === "[") {
        var stack = [str[pos]];
        var body = str[pos];

View on GitHub (pinned to b608633a7e)

Solutions

  1. Quote the offending value in the attribute: change {flag: nope} to {flag: 'nope'} or strict {"flag": "nope"}
  2. If the value must be a literal, spell it exactly: true, false, null
  3. When generating the attribute server-side, emit strict JSON via json_encode/JSON.stringify instead of hand-concatenating
  4. Wrap the failing oc.request()/oc.parseJSON() call in try/catch to log which element's attribute is broken (the message includes the raw fragment near the failure)

Example fix

<!-- before -->
<button data-request="onSave" data-request-data="{confirm: nope}">Save</button>

<!-- after -->
<button data-request="onSave" data-request-data="{confirm: 'nope'}">Save</button>
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: bare t/n words must be the exact literals
function checkBareTokens(attrValue) {
  return !/(^|[\[{,:\s])(t(?!rue\b)|n(?!ull\b))[\w.+-]*/.test(attrValue);
}

Try / catch

try {
  oc.request(el, 'onSave');
} catch (e) {
  if (/Broken JSON boolean body/.test(e.message)) {
    console.error('Bad keyword in', el.getAttribute('data-request-data'), e.message);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: oc.request(el) or oc.parseJSON on a value like {ok: tru}, {status: nope}, or data-request-data="{flag: nul}" - a bare word starting with t or n that is not exactly true/null. Also reachable via data-request-update / data-request-query attribute values parsed with parseJson:true.

Common situations: Typos in hand-written data attributes (tru, nul, Null); template engines (Blade/Twig) interpolating a PHP value without quotes so it lands as a bare word; HTML entity encoding (&quot;) stripping the quotes around a word; content management authors editing partial markup who forget the relaxed syntax still requires quoting non-literal words.

Related errors


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