json-path/JsonPath · error · InvalidModificationException
Invalid add operation. $ is not an array
Error message
Invalid add operation. $ is not an array
What it means
The root ('$') PathRef.add appends a value to the root only when the root is an array. If the root document is a JSON object (or scalar), there is nothing to append to, so it throws InvalidModificationException 'Invalid add operation. $ is not an array'.
Source
Thrown at json-path/src/main/java/com/jayway/jsonpath/internal/PathRef.java:127
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) {
if(configuration.jsonProvider().isMap(parent)){
configuration.jsonProvider().setProperty(parent, key, newVal);
} else {
throw new InvalidModificationException("Invalid put operation. $ is not a map");
}
}
@Override
public void renameKey(String oldKeyName, String newKeyName, Configuration configuration) {
Object target = parent;
if(targetInvalid(target)){
return;
}View on GitHub (pinned to 62a4c9f0f6)
Solutions
- Target the actual array path, e.g. JsonPath.add(document, "$.items", newVal, conf).
- Check isArray on the root (configuration.jsonProvider().isArray(root)) before adding.
- If the root is a map and you want a new key, use put with an explicit key instead of add.
- Unwrap the document first if the producer nests your array under a known key.
Example fix
// before JsonPath.add(document, "$", newItem, conf); // root is an object // after JsonPath.add(document, "$.items", newItem, conf);
Defensive patterns
Strategy: type-guard
Validate before calling
Object root = JsonPath.parse(document).json();
if (!(root instanceof List)) {
throw new IllegalArgumentException("Root is not an array; use put on a nested object path or add on $.items");
} Type guard
boolean rootIsArray(Object doc, Configuration conf) {
Object root = JsonPath.parse(doc, conf).json();
return conf.jsonProvider().isArray(root);
} Try / catch
try {
JsonPath.add(document, "$", newVal, conf);
} catch (InvalidModificationException e) {
// root is not an array: fall back to the known array path
JsonPath.add(document, "$.items", newVal, conf);
} Prevention
- Inspect the document root shape before choosing add vs put
- Target the actual array property (e.g. $.items), not "$"
- Validate API response shape before mutating — roots vary across endpoints
- Prefer explicit nested paths over assuming the root type
When it happens
Trigger: Calling JsonPath.add(document, "$", newVal, configuration) where the parsed root is a JSON object, e.g. trying to append to a document whose top level is an object like {"items": [...]}.
Common situations: Assuming the document root is an array while the API returns an object wrapper; appending to the wrong level — the intended array is at "$.items", not at the root; documents whose shape differs across environments.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Invalid set operation
- Invalid map operation
- Invalid delete operation
- Invalid put operation. $ is not a map
- Could not find matching close quote for %s when parsing : %s
AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11).
Data as JSON: /api/errors/51b2402bed4cfbe1.
Report an issue: GitHub.