json-path/JsonPath · error · InvalidModificationException

Put can not be performed to multiple properties

Error message

Put can not be performed to multiple properties

What it means

PathRef is an internal reference to the JSON location a path resolved to. When a JsonPath with a wildcard/definite multi-match (e.g. '$..[*]' or '$.store.*') resolves to MORE THAN ONE property, calling JsonPath.put() on the result cannot know which single property to modify, so the multi-property PathRef variant unconditionally throws InvalidModificationException. Only modification APIs (put/add/renameKey) are affected; reads still work.

Source

Thrown at json-path/src/main/java/com/jayway/jsonpath/internal/PathRef.java:320

                    configuration.jsonProvider().setProperty(parent, property, mapFunction.map(currentValue, configuration));
                }
            }
        }

        public void delete(Configuration configuration){
            for (String property : properties) {
                configuration.jsonProvider().removeProperty(parent, property);
            }
        }

        @Override
        public void add(Object newVal, Configuration configuration) {
            throw new InvalidModificationException("Add can not be performed to multiple properties");
        }

        @Override
        public void put(String key, Object newVal, Configuration configuration) {
            throw new InvalidModificationException("Put can not be performed to multiple properties");
        }

        @Override
        public void renameKey(String oldKeyName, String newKeyName, Configuration configuration) {
            throw new InvalidModificationException("Rename can not be performed to multiple properties");
        }

        @Override
        public Object getAccessor() {
            return Utils.join("&&", properties);
        }
    }
}

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Read the matched objects with JsonPath.read()/DocumentContext, loop over them, and perform the modification per element with a definite path (e.g. '$.store.book[0].price') per index.
  2. Use the map/list returned by read() as plain Java objects, mutate them, and return/re-serialize them instead of using put().
  3. Narrow the path so it resolves to exactly one property (add an index or unique key filter) before calling put().

Example fix

// before
JsonPath.put(json, "$.store.book[*]", "inStock", true); // InvalidModificationException
// after
List<Map<String, Object>> books = JsonPath.read(json, "$.store.book[*]");
for (int i = 0; i < books.size(); i++) {
    books.get(i).put("inStock", true); // mutate the resolved maps
}
Defensive patterns

Strategy: validation

Validate before calling

Object matched = JsonPath.read(json, path);
boolean isMulti = matched instanceof java.util.List && ((java.util.List<?>) matched).size() > 1;
if (isMulti) {
    throw new IllegalStateException("Path matches multiple properties; use read+loop instead of put(): " + path);
}

Try / catch

try {
    JsonPath.put(json, path, key, value);
} catch (InvalidModificationException e) {
    List<Map<String, Object>> items = JsonPath.read(json, path);
    for (Map<String, Object> item : items) item.put(key, value);
}

Prevention

When it happens

Trigger: Calling JsonPath.put(json, "key", value) (or Configuration.addOperation / com.jayway.jsonpath.DocumentContext.put) where the path expression contains a wildcard or filter that matches multiple properties in an object, e.g. '$.store.book[*].put' or path '$..author' evaluated with a definite path that resolves to several map entries. Any put() on the PathRef whose 'properties' list has more than one element hits PathRef.java:320.

Common situations: Developers want to 'set a field on every matched object' using put() with a wildcard path; put() only works when the path points at exactly one property. Also seen after switching from a definite single-path to a '$..*' style path, or when using path() plus explicit PUT operations on multi-valued results.

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/89585460bc9b40f9. Report an issue: GitHub.