json-path/JsonPath · error · InvalidModificationException
Invalid map operation
Error message
Invalid map operation
What it means
The root ('$') PathRef also rejects convert (map/MapFunction application): transforming the entire document via the root path is not a supported operation, and the implementation throws InvalidModificationException 'Invalid map operation' unconditionally.
Source
Thrown at json-path/src/main/java/com/jayway/jsonpath/internal/PathRef.java:114
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");
}
}
@Override
public void put(String key, Object newVal, Configuration configuration) {View on GitHub (pinned to 62a4c9f0f6)
Solutions
- Apply the MapFunction to a concrete sub-path such as "$.items[*]" rather than "$".
- Iterate specific fields and map each individually instead of transforming the root.
- For whole-document transformation, perform it outside JsonPath (process the parsed object directly).
- Filter out root matches ("$") in dynamic path-processing loops.
Example fix
// before JsonPath.map(document, "$", ctx -> upperCaseAll(ctx), conf); // throws // after JsonPath.map(document, "$.names[*]", ctx -> ctx.toString().toUpperCase(), conf);
Defensive patterns
Strategy: validation
Validate before calling
if ("$".equals(path)) {
throw new IllegalArgumentException("Cannot JsonPath.map the root; transform concrete sub-paths instead");
} Try / catch
try {
JsonPath.map(document, path, mapFunction, conf);
} catch (InvalidModificationException e) {
throw new IllegalStateException("Map at path '" + path + "' is not supported (root cannot be mapped)", e);
} Prevention
- Apply MapFunctions to leaf or wildcard sub-paths like $.items[*]
- Transform the whole document by post-processing the parsed object directly
- Filter "$" out of dynamically collected path lists before mapping
- Remember root-level set/map/delete are all intentionally unsupported
When it happens
Trigger: Calling JsonPath.map(document, "$", mapFunction, configuration) with the root path "$".
Common situations: Applying a MapFunction to the whole document believing it acts like a deep transform; dynamic code that maps every matched path including the root; porting per-field map code and accidentally leaving the path as "$".
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 set 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/33e0110db791c3ec.
Report an issue: GitHub.