json-path/JsonPath · error · InvalidModificationException

Can only add properties to a map

Error message

Can only add properties to a map

What it means

PathRef.put() sets a key/value property on the JSON object located by an index-based path. The library only allows put() when the target element is a map; if the element resolved at [parent, index] is an array, scalar, or invalid, put() throws InvalidModificationException("Can only add properties to a map").

Source

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

            if(targetInvalid(target)){
                return;
            }
            if(configuration.jsonProvider().isArray(target)){
                configuration.jsonProvider().setProperty(target, null, value);
            } else {
                throw new InvalidModificationException("Can only add to an array");
            }
        }

        public void put(String key, Object value, Configuration configuration){
            Object target = configuration.jsonProvider().getArrayIndex(parent, index);
            if(targetInvalid(target)){
                return;
            }
            if(configuration.jsonProvider().isMap(target)){
                configuration.jsonProvider().setProperty(target, key, value);
            } else {
                throw new InvalidModificationException("Can only add properties to a map");
            }
        }

        @Override
        public void renameKey(String oldKeyName, String newKeyName, Configuration configuration) {
            Object target = configuration.jsonProvider().getArrayIndex(parent, index);
            if(targetInvalid(target)){
                return;
            }
            renameInMap(target, oldKeyName, newKeyName, configuration);
        }

        @Override
        public Object getAccessor() {
            return index;
        }

        @Override

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Verify the target element is a map (jsonProvider().isMap / target instanceof Map) before calling put().
  2. If the target is an array, use add(value) to append instead of put(key, value).
  3. Correct the path so it points at the object that should receive the property.
  4. Catch InvalidModificationException around mutation code when document shapes vary.

Example fix

// before
context.put("$.data[0]", "status", "ok"); // throws if data[0] is an array
// after
Object target = context.read("$.data[0]");
if (target instanceof Map) {
    context.put("$.data[0]", "status", "ok");
} else {
    context.add("$.data[0]", "ok");
}
Defensive patterns

Strategy: type-guard

Validate before calling

Object el = context.read("$.data[0]");
if (!(el instanceof Map)) throw new IllegalStateException("$.data[0] is not a map");
context.put("$.data[0]", key, value);

Type guard

private static boolean isMap(Object o) { return o instanceof Map; }

Try / catch

try { context.put(path, key, value); } catch (InvalidModificationException e) { log.warn("put() target at {} is not a map", path); }

Prevention

When it happens

Trigger: Calling JsonPath.parse(...).put(path, key, value) where the index-based path resolves to an element that is not a JSON object — most commonly the element is an array `[...]` and add() was the intended operation.

Common situations: Confusing add() and put() semantics when the document shape changed; passing a path to an array element while intending to append; upstream API switched an object field to an array between versions.

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