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

  1. Apply the MapFunction to a concrete sub-path such as "$.items[*]" rather than "$".
  2. Iterate specific fields and map each individually instead of transforming the root.
  3. For whole-document transformation, perform it outside JsonPath (process the parsed object directly).
  4. 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

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


AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11). Data as JSON: /api/errors/33e0110db791c3ec. Report an issue: GitHub.