Troubleshooting
JSON Patch Errors: Why a Patch Fails
Almost every JSON Patch failure comes down to four causes: the target does not exist, the path is not a valid pointer, an array index is wrong, or a test found the document in an unexpected state. Find your error below.
A JSON Patch operation fails when its path points at a value that does not exist, the path is not valid JSON Pointer syntax, an array index is out of range, or a test value does not match. Evaluation stops at the first failing operation.
Error lookup table
| Symptom | Cause | Fix |
|---|---|---|
| "path does not exist" on remove or replace | The target path is not in the document - a typo, a missing key, or an earlier operation already removed or shifted it. | Print the document right before the patch runs and walk the path segment by segment. Remember operations see the document left by previous operations. |
| "array index out of bounds" (or "index out of range") | The index is greater than the last valid position. For add, anything above the array length; for the others, anything above length - 1. | Use /- to append without knowing the length, and when removing several elements, remove from the highest index down. |
| "invalid token" or "bad escape" in a path | The path is not a valid JSON Pointer: no leading slash, a leading zero in an array index (/items/01), or a stray ~ not followed by 0 or 1. | Escape ~ as ~0 and / as ~1, start every path with /, and write array indexes without leading zeros. |
| test operation fails | The value at the path is not exactly equal to the test value - often a string/number mismatch ("1" vs 1) or the document changed since the patch was written. | Compare types, not just values. A failing test is the patch protecting you - find out why the document differs before forcing it. |
| "cannot move a value into one of its children" | move tries to place a value inside itself, like moving /a to /a/b. | Choose a destination outside the source subtree. |
| add fails but the path looks right | add can create the final step of a path, but every parent segment must already exist. /a/b/c fails when /a/b does not. | Create intermediate objects or arrays with earlier add operations. |
| Error before any operation runs | The patch document itself is malformed: not valid JSON, not an array, an operation missing op or path, or an unknown op. | Validate the patch JSON first. The six operations are add, remove, replace, move, copy, test - anything else is rejected. |
The most common one: array index out of bounds
Document
{ "items": ["a", "b"] }Patch - fails
[
{ "op": "remove", "path": "/items/5" }
]The array has two elements, so the only valid indexes are 0 and 1 - index 5 does not exist and the patch fails. Two patterns cause this constantly: indexes that were valid when the patch was written but shifted after earlier operations, and counting from 1 instead of 0. Append with /- instead of a computed index, and remove from the highest index down. Full treatment in JSON Patch and arrays.
When test fails, it is doing its job
A test operation fails the patch by design when reality differs from your assumption - that is optimistic concurrency protecting the document, not a bug in your patch. The one false alarm worth checking first: types. JSON has no implicit conversion, so "1" (string) and 1 (number) are different values, and so are true and "true".
A debugging workflow that works
- Paste the document and patch into the apply or verify tool - it names the failing operation in plain language instead of a raw library exception.
- Apply the patch one operation at a time to find the exact step that breaks.
- Add a
testbefore the failing operation to see what the document actually contains at that path. - Check array indexes after every earlier
addorremove- they shift.
Reference
Error conditions per operation are defined throughout RFC 6902, section 4, and the rule that evaluation stops at the first error in section 5. Path syntax errors come from RFC 6901, section 3.
See a failing patch explained
Open the apply tool with a patch that fails on an out-of-bounds index - the tool explains the error in plain language.
Open the failing example