Build1 distinct publisher3 min readUpdated
Seven Python parsers, 300 labelled malformed LLM outputs. On recoverable cases json-repair wins by two; count the 25 unrecoverable ones and it loses by seventeen.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
The maintainer of jsonshim, a small stdlib tool that pulls JSON out of a language model's reply [1], built a 300-case conformance suite called MALFORMED-300 and ran seven Python parsers through it once each, on Python 3.12.3, with nothing tuned afterwards [2][4]. The transferable part is not the ranking but the scoring rule: 25 of the 300 cases are unrecoverable, the model having emitted only `{` or a bare `<redacted>` placeholder, and a library passes those only by refusing, with `{}` graded a failure rather than a near miss [6]. The author reports two columns, on the grounds that these libraries do not share a design goal and a single number would quietly punish some of them for a deliberate choice [5]. The narrow column drops the unrecoverable cases and asks only what a parser returns when there is something to return [7]. There, json-repair beats jsonshim 264 to 262 [8]. Widen it and the order inverts: jsonshim declines 20 of the 25 unrecoverable cases, json-repair declines 1, because json-repair is built to always hand you something [9]. That is 265 of 300 against 282 [1][23], a 17-case swing produced entirely by refusal policy [2] on top of a two-case deficit in recovery [8]. The author's own framing is that always returning is a legitimate design, arguably the right one when you would rather render an empty card than an error, and the wrong one when the parsed object goes into a database or a tool call [10]. The mechanism is that an invented value does not raise and does not log; it arrives looking exactly like data [11]. The worst case in the suite is `{"user_id": <redacted>}` parsed into `{"user_id": "<redacted>"}`, a redaction turned into a user id [12]. jsonshim also fails that one, and the author left it failing on the stated grounds that patching it after seeing the score would convert 94.0% from a measurement into a claim [13][3]. Four of the seven are doing a different job. json5, pyjson5, demjson3 and dirtyjson are dialect parsers reading a looser grammar than strict JSON [14], so they clear grammar categories - unquoted keys 25/25 for all four, trailing commas 20/25, single quotes 16/25, comments 16/25 - and score a flat zero on code fences, prose wrappers and truncation [15][16]. A reply that wraps a fenced object in reasoning text has not produced malformed JSON; locating the payload and parsing the payload are separate problems, and only two of the seven do both [17]. On that basis the author argues the standing advice to "just use json5" answers a question most LLM output does not ask [18]. The per-category grid also splits the two extractors: json-repair takes wrappers 25 to 17, jsonshim takes Python literals 25 to 21 [19]. The harness is the reason to take any of this seriously. Each library is called through its own documented entry point and lenient mode, in an adapters file kept to about a hundred lines so it can be audited [20]; no input is pre-cleaned and every parser sees the identical raw string [21]; the only post-processing normalises library-specific container and sentinel types to plain `dict`, `list` and `None` [22]. Before any third-party row was scored, the harness had to reproduce a previously published jsonshim result exactly, 282/300 with 5 invented values and 4 false refusals, and it did [23]. Ground truth is produced by construction, with a checkpointing renderer emitting the expected value before the malformed text exists, so no parser was ever consulted about the right answer [24]. Two things to watch. The arithmetic is tight enough to check: 18 total failures, of which 5 are unrecoverable cases not declined, leaving 13 among the recoverable set [4].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
jsonshim is a small stdlib tool, maintained by the article's author, that pulls JSON out of a language model's reply.
The author built a 300-case conformance suite for that job, named MALFORMED-300.
The author had previously published results for his own parser on the suite: 18 failures, five of them values invented where the model had produced nothing.
The benchmark covered seven parsers and 300 labelled cases on Python 3.12.3, one run each, with nothing tuned afterwards.
25 of the 300 cases are unrecoverable - the model emitted only `{`, or a bare `<redacted>` placeholder - and those pass only by refusing; returning `{}` there is graded a failure, not a near miss.
The 275 recoverable cases drop the refusal question and ask only what a library gets back when there is something to get.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Detailed and self-auditable, but entirely vendor-produced
The methodological disclosure is unusually strong for a blog benchmark: documented entry points, a deliberately small auditable adapter layer, no input pre-cleaning, value-level normalisation, ground truth generated by construction before the malformed text exists, a published corpus hash, a shipped grading contract, and a replication gate that had to reproduce a previously published 282/300 before third-party rows were trusted. What caps the score is that every figure comes from the tool author's own harness with one run per parser, no variance data, and no independent re-run; the full label rationale sits behind a paid licence, so only 30 of 300 cases are publicly checkable.
No third-party uptake evidenced
The supplied sources document publication and packaging only — a leaderboard, a CC0 sample, a paid corpus licence and an invitation for others to submit results. There is no disclosed user, deployment, download, star, dependent-project or CI integration outside the author's own pipeline, so adoption cannot be measured without inferring facts the sources do not contain.
Restrained framing, but self-graded and unreplicated
Rhetorically the story understates rather than oversells: the author leads with losing the column he cared about, names five invented values in his own parser, leaves the worst failing case unfixed to avoid turning a measurement into a claim, tells readers to read the grid rather than the total, and flags the cross-runtime comparison as uncontrolled. The gap that remains is structural, not tonal — comparative verdicts about six third-party libraries rest on one un-replicated run by the party that ships one of the entrants and sells the corpus, and the headline 'wins by two / loses by seventeen' framing is only as sound as the suite's own grading contract, most of which is not publicly inspectable.
Vendor benchmarks its own tool and monetises the corpus
The benchmark's author writes jsonshim, one of the seven entrants, defines the grading contract that decides the all-300 column jsonshim wins, sells the full corpus at EUR 29/EUR 99 with channel-tagged checkout links, and publishes via an automated content pipeline that generates the posts. Mitigations are real and disclosed — the recovery column is conceded to a competitor, self-failures are named and left unfixed, the sample and scorer are CC0, and authorship is stated outright — which is why this is not scored at the ceiling.
Internally coherent, single-source
The two items agree on every overlapping number (262/264, 275/25, five invented values, the unfixed redaction case) and the methodology is specific enough to falsify, which supports moderate confidence in the reported figures as measurements. Confidence is held down because both items come from the same dev.to account and pipeline, no independent party has re-run the corpus, adoption is entirely unevidenced, and the labels that decide most scores are only partly public.
build
Four Clocks, One Timeout: Why Long-Audio Transcription Needs a State Machine1 distinct publisher
build
The kill switch that deletes your evidence is not a kill switch1 distinct publisher
build
A GenAI comic pipeline cut iteration passes from 20+ to under 5, then lost on reception1 distinct publisher
build
The command injection fix Cursor writes still runs your code1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
2 articles · August 19, 2026