octobercms/october · error · Error
Broken JSON object near ${result}
Error message
Broken JSON object near ${result} What it means
Thrown at the end of the object branch of JsonParser.parseString (October CMS AJAX framework). The state machine walks the {..} literal key-by-key (needKey/needBody states, lenient commas, relaxed quotes) and returns only when it places the closing '}'. If the input ends before that brace is produced, the partial result accumulated so far is reported and the parse aborts.
Source
Thrown at modules/system/assets/js/framework.js:2146
} else if (type === "afterBody" || type === "needKey") {
var last = i;
while (str[last] === "," || this.isBlankChar(str[last])) {
last++;
}
if (str[last] === "}" && last === str.length - 1) {
while (result[result.length - 1] === ",") {
result = result.substr(0, result.length - 1);
}
result += "}";
return result;
} else if (last !== i && result !== "{") {
result += ",";
type = "needKey";
i = last - 1;
}
}
}
throw new Error("Broken JSON object near " + result);
}
if (str[0] === "[") {
var result = "[";
var type = "needBody";
for (var i = 1; i < str.length; i++) {
if (" " === str[i] || "\n" === str[i] || " " === str[i]) {
continue;
} else if (type === "needBody") {
if (str[i] === ",") {
result += "null,";
continue;
}
if (str[i] === "]" && i === str.length - 1) {
if (result[result.length - 1] === ",") result = result.substr(0, result.length - 1);
result += "]";
return result;
}
var body = this.getBody(str, i);View on GitHub (pinned to b608633a7e)
Solutions
- Append the missing closing '}' to the object literal
- Fix any inner incomplete value first - a broken value can consume the real closer
- Round-trip the value through oc.parseJSON (or strict JSON.parse) in the console/CI to catch unclosed objects before shipping markup
Example fix
<!-- before -->
<div data-request-data="{page: 2, sort: 'name'">...</div>
<!-- after -->
<div data-request-data="{page: 2, sort: 'name'}">...</div> Defensive patterns
Strategy: try-catch
Validate before calling
function objectLiteralCloses(s) {
const t = s.trim();
if (t[0] !== '{') return true;
const closes = (t.match(/}/g) || []).length;
const opens = (t.match(/{/g) || []).length;
return closes === opens;
} Try / catch
try { const d = oc.parseJSON(raw); } catch (e) { if (/Broken JSON object near/.test(e.message)) console.error('Unterminated { - missing closing brace:', e.message); } Prevention
- Every '{' needs its '}' - count them after editing
- Fix broken inner values first; they can swallow the closer
- Lint attribute JSON in CI with a round-trip parse
When it happens
Trigger: oc.parseJSON("{a: 1") or data-request-data="{page: 2, sort: 'name'" - object literal missing its final }; also inner values left mid-way ({a: ) that consume input without completing the state machine.
Common situations: Hand-edited attribute values missing the closing brace; template concatenation dropping the last character; partial JSON pasted into markup; refactors that delete the trailing } while editing the last pair.
Related errors
- Broken JSON boolean body near ${str}
- Broken JSON number body near ${body}
- Error parsing the ${name} attribute value. ${e}
- Error parsing the ${name} attribute value. ${e}
- Broken JSON array near ${result}
AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21).
Data as JSON: /api/errors/3d38a4224992bde6.
Report an issue: GitHub.