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;
}
@OverrideView on GitHub (pinned to 62a4c9f0f6)
Solutions
- Verify the target element is a map (jsonProvider().isMap / target instanceof Map) before calling put().
- If the target is an array, use add(value) to append instead of put(key, value).
- Correct the path so it points at the object that should receive the property.
- 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
- Check isMap (instanceof Map) on the resolved element before put().
- Remember: arrays take add(), objects take put().
- Validate document shape against a schema when the producer may change it.
- Handle exceptions when mutating documents from untrusted or versioned sources.
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
- Can only add to an array
- Can only rename properties in a map
- Add can not be performed to multiple properties
- Failed to evaluate exists expression
- Filter: %s can not be applied to primitives. Current context
AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11).
Data as JSON: /api/errors/d7a4a1bac8e32b88.
Report an issue: GitHub.