How to Fix Broken JSON from LLMs

LLMs are probabilistic. Your code is deterministic. Shim bridging the gap.

Failure: JSON Truncation

The Problem: LLMs hit token limits or timeout mid-response. You receive an incomplete JSON object that `JSON.parse()` rejects.

// Received Output:

{"users": [{"id": 1, "name": "Alice"}, {"id": 2, "name":

Result: Production crash. Loss of data. Broken UI.

The Shim Fix:

Shim detects the truncation and instantly injects the missing closing brackets and braces to make the JSON syntactically valid.

// Repaired by Shim:

{"users": [{"id": 1, "name": "Alice"}, {"id": 2}]}

Latency: <0.05ms

Failure: Markdown Code Fences

The Problem: Even in "JSON mode," LLMs often wrap outputs in markdown backticks: ```json ... ```.

```json { "status": "ok", "data": 123 } ```

The Shim Fix:

Shim automatically strips markdown indicators, whitespace, and non-JSON preamble text before your parser ever sees it.

{ "status": "ok", "data": 123 }

Action: Intercept & Strip

Failure: Schema Drift

The Problem: The LLM returns a string when you expect a number, or neglects a required field. Downstream services fail validation.

Type Coercion

LLM returns "30" for age. Your DB expects number. Shim coerces the type instantly.

Value Recovery

LLM returns null for a required boolean. Shim defaults or repairs based on your schema.

Implementation

Receive. Repair. Return.

Shim sits between your LLM and application logic.

const response = await fetch('https://api.shim.so/v1/repair', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer sk_xxx' },
  body: JSON.stringify({ 
    raw_output: llmOutput,
    schema: myJsonSchema // Optional
  })
});

const { repaired, metadata } = await response.json();
  • Sub-millisecond repair time
  • Zero data persistence policy
  • Streaming compatible

Shim vs Alternatives

FeatureRetriesFixingParserShim
Latency2 - 5sFull output wait<10ms total
StreamingNoNo (buffering)Yes
Cost2x TokensHigh InfraFlat rate
ConfidenceNoneNoneStructured