json-path/JsonPath · error · InvalidModificationException
Invalid set operation
Error message
Invalid set operation
What it means
The '$' (root) PathRef implementation intentionally rejects set: the JSON root can only hold a map or array container, and assigning a scalar replacement to the entire document is not a supported modification. Any set call that resolves to the root throws InvalidModificationException 'Invalid set operation'.
Source
Thrown at json-path/src/main/java/com/jayway/jsonpath/internal/PathRef.java:110
public static PathRef createRoot(Object root){
return new RootPathRef(root);
}
private static class RootPathRef extends PathRef {
private RootPathRef(Object parent) {
super(parent);
}
@Override
Object getAccessor() {
return "$";
}
@Override
public void set(Object newVal, Configuration configuration) {
throw new InvalidModificationException("Invalid set operation");
}
public void convert(MapFunction mapFunction, Configuration configuration){
throw new InvalidModificationException("Invalid map operation");
}
@Override
public void delete(Configuration configuration) {
throw new InvalidModificationException("Invalid delete operation");
}
@Override
public void add(Object newVal, Configuration configuration) {
if(configuration.jsonProvider().isArray(parent)){
configuration.jsonProvider().setArrayIndex(parent, configuration.jsonProvider().length(parent), newVal);
} else {
throw new InvalidModificationException("Invalid add operation. $ is not an array");
}View on GitHub (pinned to 62a4c9f0f6)
Solutions
- Set a concrete sub-path (e.g. "$.field") instead of the root path.
- To replace the whole document, assign the new value to your document variable directly instead of using JsonPath.set.
- If you only need to change part of the document, use put/add on the appropriate container path.
- Guard against path=="$" in code that computes paths dynamically.
Example fix
// before JsonPath.set(document, "$", newRoot, conf); // throws // after document = newRoot; // replace reference, or: JsonPath.set(document, "$.field", newRoot, conf);
Defensive patterns
Strategy: validation
Validate before calling
if ("$".equals(path)) {
throw new IllegalArgumentException("Cannot JsonPath.set the root; assign the document reference instead");
} Try / catch
try {
JsonPath.set(document, path, newVal, conf);
} catch (InvalidModificationException e) {
throw new IllegalStateException("Set at path '" + path + "' is not supported (root cannot be set)", e);
} Prevention
- Never use "$" as a set target; pick a concrete sub-path
- Replace the document variable itself to swap the whole document
- In dynamic path pipelines, skip or special-case root matches
- Use put/add for container-level changes instead of set
When it happens
Trigger: Calling JsonPath.set(document, "$", newVal, configuration) — i.e. using the root path "$" as the set target.
Common situations: Trying to replace the whole document via set; generic code that builds paths dynamically and degenerates to "$"; misusing set where map/array put or add operations were intended.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Invalid map operation
- Invalid delete operation
- Can only rename properties in a map
- Invalid add operation. $ is not an array
- Invalid put operation. $ is not a map
AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11).
Data as JSON: /api/errors/68e765967e00782c.
Report an issue: GitHub.