FreeToGenerate.com

Apply a patch one operation at a time and watch the document change. When an operation fails, see exactly what the earlier ones had already done. Nothing is uploaded.

Try one:

The document the patch will be applied to. It is never modified in place.

An array of operations. Each needs an op and a path; add, replace and test also need a value, and move and copy need a from.

Result

Failed at operation 2

The value at that location is not the one the test expected. Types count as well as values, so the number 10 does not match the string 10.

One operation failed, so this tool discards the whole result. That is a choice, not a rule — see below.

What the document had already become

{
  "a": {
    "b": {
      "c": 42
    }
  }
}

RFC 6902 does not require a failed patch to be rolled back. Section 5 says only that the patch is not to be deemed successful; the atomicity everyone quotes comes from the HTTP PATCH method in a different document. So the state above is what a library that applies operations in place would leave you with.

Operation by operation

The document after each operation, which is the part a single answer hides.

StepOperationOutcome
1replace /a/b/c = 42
Document after this step
{
  "a": {
    "b": {
      "c": 42
    }
  }
}
applied
2test /a/b/c = "C"failed

Everything here runs in your browser. Nothing you paste is uploaded.

Also available in: Español · Português · Français · العربية

JSON Patch tester: apply RFC 6902 operations step by step

Run a patch against a document, see the result after each operation, and find out what a failure actually leaves behind.

What is JSON Patch?

JSON Patch is a small format for describing changes to a JSON document rather than sending the whole thing. A patch is an array of operations, each naming what to do and where: add, remove, replace, move, copy and test. RFC 6902 defines all six in about eight pages, and every location is written as a JSON Pointer, which is the sibling format for naming exactly one place in a document.

It exists because sending a whole document to change one field is wasteful and ambiguous — two clients doing that will silently overwrite each other. A patch says what changed, which is smaller on the wire and specific enough to reject if the document has moved on underneath you. That is what the sixth operation is for: test does not change anything, it asserts, and a patch whose first operation is a test is a change that refuses to apply to the wrong document.

This page runs a patch against a document and shows the result after every single operation, not just at the end. That matters more than it sounds, for a reason the next-but-one section is about.

How to use it

  1. Paste the document. It is never modified in place — every operation works on a copy, so your original is intact whatever the patch does.
  2. Paste the patch. An array of operations. The sample buttons load five cases: a test that fails halfway, an array insert, a test used as a guard, a move the specification forbids, and an index past the end of an array.
  3. Read the trace. Each row is one operation, and you can expand any of them to see the whole document as it stood at that moment. A failure names the specific rule rather than reporting nothing.

A JSON Patch is not atomic, and the spec does not say it is

Everyone knows that a failed patch leaves the document untouched. It is the first thing anybody tells you about the format, and it is not what RFC 6902 says.

Section 5 says that on a failure, evaluation should terminate and application of the entire patch document shall not be deemed successful. Read that carefully: it is a statement about the verdict, about whether the patch counts as having worked. It says nothing about undoing the operations that already ran. The atomicity everyone quotes arrives one sentence later and from somewhere else entirely — a note that the HTTP PATCH method is atomic, as per a different document, the one that defines that method.

So the guarantee belongs to the transport rather than to the format. Send a patch over HTTP PATCH and the server is required to apply all of it or none of it. Hand the same patch to a library in your own process and whether you are left holding a half-modified object is that library's business, not something the standard settles for you. The specification's own worked example is a two-operation patch whose test fails second, and it says the document ends up unchanged — because it is describing the HTTP case.

That is why this tool shows every intermediate state. When a patch fails here, it discards the result and tells you so, which is a choice rather than a rule; and it shows you what the document had already become, which is what a tool printing one final answer hides from you.

Three rules that surprise people

Adding to an array inserts, it does not overwrite. Point add at index one of a three-element array and you get a four-element array, with everything from index one shifted right. If you wanted to overwrite, that is replace. The index may equal the length, which appends, but anything past that is an error rather than a sparse write — and the pointer syntax has a dash that means after the last element, which says append far more clearly than a number does.

The same operation has a quieter trap. Adding an array as a value appends that array as a single element, so a one-element list plus an array of two becomes a list of two, the second of which is itself a list. The specification includes that as its own worked example, which is usually a sign that people expected the other thing.

Move carries a rule with no analogue among the other operations: the source may not be a proper prefix of the destination, or in the specification's own words, a location cannot be moved into one of its children. It is obvious once stated and easy to write by accident when the paths are long.

And test compares types as well as values. The number ten and the string ten are different, and a test asserting one against the other fails. That is the behaviour you want from a precondition, but it catches people who have been through a form or a query string, where everything arrived as text.

Honest limitations

This applies patches; it does not generate them. Producing a minimal patch between two documents is a different problem with several defensible answers, and the specification does not define one.

There is one example in the standard this tool cannot run, and the reason is worth knowing. It is a patch whose operation object contains the same member twice — op appears as both add and remove — and the specification notes that JSON only says member names should be unique, with no standard handling for duplicates. Any JavaScript parser resolves that silently by keeping the last one, so the defect the example exists to describe is destroyed before a patch engine ever sees the document. It is a property of the parser, not of the patch format, and no implementation that receives already-parsed JSON can detect it.

Finally, this tool discards the result when any operation fails. That is deliberate and it is the safer default, but it is a decision this page made rather than one the format imposes — which is exactly why the half-applied document is shown beside it instead of being thrown away silently.

Why is it free?

Walking a document and applying a handful of operations is a few hundred lines of string and array handling, and your browser does it as you type. No server sees your JSON, so there is nothing to meter and no account to create.

Nothing is uploaded. Whatever you paste stays in this tab.