json-path/JsonPath · error · UnsupportedOperationException
Cannot create JSON element from null
Error message
Cannot create JSON element from null
What it means
JakartaJsonProvider.wrap() converts a plain Java object into a Jakarta JSON-P JsonValue. It handles JsonValue, Boolean, CharSequence, Number, Collection, Map and the builder types; any other type (custom POJO, Date, enum, etc.) hits the final else and throws UnsupportedOperationException('Cannot create JSON element from <ClassName>'). The message names the unsupported class (note: if obj is null, a NullPointerException occurs earlier at obj.getClass(), though null normally becomes JsonValue.NULL before that branch).
Source
Thrown at json-path/src/main/java/com/jayway/jsonpath/spi/json/JakartaJsonProvider.java:424
return defaultJsonProvider.createValue(v);
}
} else if (obj instanceof Collection) {
JsonArray result = jsonBuilderFactory.createArrayBuilder((Collection<?>) obj).build();
return mutableJson ? proxyAll(result) : result;
} else if (obj instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) obj;
JsonObject result = jsonBuilderFactory.createObjectBuilder(map).build();
return mutableJson ? proxyAll(result) : result;
} else if (obj instanceof JsonArrayBuilder) {
JsonArray result = ((JsonArrayBuilder) obj).build();
return mutableJson ? proxyAll(result) : result;
} else if (obj instanceof JsonObjectBuilder) {
JsonObject result = ((JsonObjectBuilder) obj).build();
return mutableJson ? proxyAll(result) : result;
} else {
String className = obj.getClass().getSimpleName();
throw new UnsupportedOperationException("Cannot create JSON element from " + className);
}
}
private JsonStructure proxyAll(JsonStructure jsonStruct) {
if (jsonStruct == null) {
return null;
} else if (jsonStruct instanceof JsonArrayProxy) {
return (JsonArray) jsonStruct;
} else if (jsonStruct instanceof JsonArray) {
List<Object> array = new ArrayList<>();
for (JsonValue v : (JsonArray) jsonStruct) {
if (v instanceof JsonStructure) {
v = proxyAll((JsonStructure) v);
}
array.add(v);
}
return new JsonArrayProxy(jsonBuilderFactory.createArrayBuilder(array).build());
} else if (jsonStruct instanceof JsonObjectProxy) {
View on GitHub (pinned to 62a4c9f0f6)
Solutions
- Convert the value before passing it: use a Map/List, String, Number, Boolean, or a JsonObjectBuilder/JsonArrayBuilder
- Serialize the POJO yourself (e.g. with a DTO mapper) into a Map<String,Object> and pass that to setProperty/setArrayIndex
- Catch UnsupportedOperationException and fall back to a String conversion (obj.toString() or a formatter) for values like Date
- Extend your wrapping layer (wrap() equivalent) to handle your domain types before delegating to the provider
Example fix
// before
provider.setProperty(doc, "created", new Date()); // UnsupportedOperationException
// after
provider.setProperty(doc, "created", new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
.format(new Date())); // String maps to JsonString Defensive patterns
Strategy: type-guard
Validate before calling
// Java
private static boolean isWrappable(Object v) {
return v == null || v instanceof JsonValue || v instanceof Boolean || v instanceof CharSequence
|| v instanceof Number || v instanceof Collection || v instanceof Map
|| v instanceof JsonArrayBuilder || v instanceof JsonObjectBuilder;
} Type guard
if (!(v instanceof String || v instanceof Number || v instanceof Boolean
|| v instanceof Map || v instanceof Collection || v instanceof JsonValue)) {
throw new IllegalArgumentException("Convert " + v.getClass() + " to Map/List before setting");
} Try / catch
try {
provider.setProperty(doc, key, value);
} catch (UnsupportedOperationException e) {
provider.setProperty(doc, key, String.valueOf(value)); // fallback: store as string
} Prevention
- Never pass POJOs, Date, or Optional values directly to JsonPath.set/put with the Jakarta provider
- Convert domain objects to Map/List DTOs before mutation
- Keep a small mapping utility (Date->ISO string, enums->name()) at mutation boundaries
- Document which value types your chosen JsonProvider supports
When it happens
Trigger: Calling setArrayIndex or setProperty (JsonPath.set/put/append APIs) with a value object the provider cannot map — e.g. a POJO, java.util.Date, Optional, or a non-supported container type; wrapping arbitrary objects into a document via mapProperty with a non-mappable payload.
Common situations: Migrating from Gson/Jackson-based providers where POJOs were serialized implicitly, to the Jakarta JSON-P provider which only maps basic types; passing Date or LocalDateTime values into JSON mutations; forgetting to convert domain objects to Map/Collection/JsonStructure first.
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
- an array or object instance is expected
- InvalidJsonException
- InvalidJsonException
- Invalid JSON
- length operation can not applied to
AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11).
Data as JSON: /api/errors/b0a05b0654e16102.
Report an issue: GitHub.