The Escape Sequences Pretty-Printers Get Wrong

A pretty-printer that handles indentation cleanly can still corrupt JSON if it mishandles escape sequences inside strings. Backslashes, unicode escapes, control characters, and forward slashes all have specific behavior rules. Getting them wrong produces JSON that parses in some libraries and fails in others, or that changes meaning silently. The site's FHIR JSON tidier handles the escape rules per RFC 8259. For the wider FHIR framing, more on FHIR for healthcare data teams has more.

The Required Escapes

RFC 8259 (JSON) requires escaping:

  • " — double quote
  • \ — backslash
  • \b \f \n \r \t — control characters
  • Any character in U+0000..U+001F range as \uXXXX

That is the required set. A formatter that emits raw control characters produces invalid JSON.

The Optional Escapes

  • / — forward slash may be escaped as \/ but does not have to be
  • \uXXXX — any character may be escaped as unicode
  • Non-ASCII characters — may be UTF-8 or \uXXXX

Each is legal in either form. Interoperability trouble hides in the choice.

The Forward-Slash Case

Escaping / as \/ is legal but not necessary. Some formatters do it, some do not.

FHIR reference strings often contain / (as in Patient/123). A formatter that escapes them produces "Patient\/123" — which parses to the same string but visually differs. Diffs light up on unimportant changes.

Rule: do not escape forward slashes. Consistency across the team matters.

For the reference-preservation angle, keeping references intact after pretty-printing is the entry.

The Unicode Escape Case

ü can be written as ü (UTF-8 bytes) or ü (escape sequence). Both parse to the same character.

Formatters that convert one form to the other change the byte content without changing the meaning. Diffs light up. Character-exact comparisons fail.

Rule: preserve whichever form was in the input. Do not normalize.

The Surrogate Pair Case

Characters outside the Basic Multilingual Plane require surrogate pairs in \uXXXX\uXXXX form. Emoji, less-common scripts, historical characters.

Some formatters break surrogate pairs (splitting them across escape sequences) or normalize them (converting to UTF-8). Either can produce invalid or corrupted output.

Test your formatter with a resource that contains emoji or Chinese characters. If the output still parses correctly, the surrogate handling is fine.

The Control-Character Case

Control characters below U+0020 must be escaped. Some formatters emit them raw (illegal). Others escape them as \uXXXX even when there is a shorter form (\n for U+000A, for instance).

The shorter form is preferred but the longer is legal. Consistency matters.

The Base64 Case

Media.data and Binary.data carry base64 strings. Base64 uses A-Z, a-z, 0-9, +, /, =. The / is a plain forward slash inside a string.

Formatters that escape / produce \/ inside base64. Parsers correctly interpret this and the byte value is unchanged. Diffs still light up on the changes.

For the memory implications of large base64 payloads, pretty-printing large Bundles without blowing memory is the entry.

The Verification Test

For every formatter you use, run this test:

  • Take a Bundle with a variety of strings — references, coded values, UTF-8 text, base64, emoji
  • Pretty-print it
  • Parse the output
  • Deep-compare the parsed structure to the parsed original
  • Fail on any structural difference

Two minutes. Catches an entire class of subtle bugs.

Team Convention

  • Do not escape forward slashes
  • Preserve the escape form of the input (UTF-8 vs \uXXXX)
  • Emit control characters using the shortest legal escape
  • Verify surrogate pairs roundtrip

Write it down. For the convention checklist, formatting conventions your team should pin down is the entry.

The Short Version

Escape only what the spec requires. Do not touch forward slashes. Preserve UTF-8 vs escape form. Test with emoji and surrogate pairs. Verify every formatter round-trips your payloads.

Blueprint-schematic diagram of JSON escape sequence handling with required, optional, and unicode escape categories and their common failure modes annotated, drawn as flat schematic lines with red accents on cream paper

Sources