octobercms/october · error · Error
Broken JSON ${str[pos] === "{" ? "object" : "array"} body ne
Error message
Broken JSON ${str[pos] === "{" ? "object" : "array"} body near ${body} What it means
Thrown while JsonParser.getBody bracket-matches an object or array body in October CMS's relaxed JSON. The parser keeps a stack of open brackets and quotes; when it encounters '}' and the innermost open bracket is not '{' (for example a '{' appearing while only '[' is open), the structure cannot be balanced and it throws, echoing the body scanned so far.
Source
Thrown at modules/system/assets/js/framework-bundle.js:2306
if (stack[stack.length - 1] === '"') {
stack.pop();
} else if (stack[stack.length - 1] !== "'") {
stack.push(str[i]);
}
} else if (str[i] === "'") {
if (stack[stack.length - 1] === "'") {
stack.pop();
} else if (stack[stack.length - 1] !== '"') {
stack.push(str[i]);
}
} else if (stack[stack.length - 1] !== '"' && stack[stack.length - 1] !== "'") {
if (str[i] === "{") {
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);
}
} else if (str[i] === "[") {
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
};
}
}View on GitHub (pinned to b608633a7e)
Solutions
- Balance the brackets in the attribute value: add the missing ']' (e.g. {items: [1,2]}) and remove the extra '}'
- Run the value through a bracket-balance check or oc.parseJSON before wiring it to a request
- Author the attribute as strict JSON generated by JSON.stringify/json_encode so tooling can validate it
Example fix
<!-- before -->
<div data-request-data="{items: [1,2}}">...</div>
<!-- after -->
<div data-request-data="{items: [1,2]}">...</div> Defensive patterns
Strategy: validation
Validate before calling
function bracketsBalanced(s) {
let depth = 0;
for (const ch of s) {
if (ch === '{' || ch === '[') depth++;
else if (ch === '}' || ch === ']') depth--;
if (depth < 0) return false; // closer with nothing open
}
return depth === 0;
}
const ok = bracketsBalanced(el.getAttribute('data-request-data') || ''); Try / catch
try { oc.request(el, 'onGo'); } catch (e) { if (/Broken JSON (object|array) body/.test(e.message)) { console.error('Unbalanced brackets in data attributes:', e.message); } } Prevention
- Auto-close/format JSON in the editor rather than editing brackets by hand
- After editing nested values, re-run oc.parseJSON in the console
- Prefer strict JSON in attributes so standard linters can validate them
When it happens
Trigger: oc.parseJSON("{items: [1,2}}") - the first '}' closes nothing because the top of the stack is '['; likewise data-request-update="{'partial': '#id'}}" with an extra closing brace inside a nested array context.
Common situations: Extra '}' typed at the end of hand-written attribute values; nesting edits (adding an array literal) without updating brackets; regex/string processing of attributes that appends stray braces; minified or hand-compressed markup losing a ']' before a '}'.
Related errors
- Broken JSON boolean body near ${str}
- Broken JSON number body near ${body}
- Broken JSON body near ${str}
- Error parsing the ${name} attribute value. ${e}
- Error parsing the ${name} attribute value. ${e}
AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21).
Data as JSON: /api/errors/306dda3dbd7a61b7.
Report an issue: GitHub.