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

  1. Convert the value before passing it: use a Map/List, String, Number, Boolean, or a JsonObjectBuilder/JsonArrayBuilder
  2. Serialize the POJO yourself (e.g. with a DTO mapper) into a Map<String,Object> and pass that to setProperty/setArrayIndex
  3. Catch UnsupportedOperationException and fall back to a String conversion (obj.toString() or a formatter) for values like Date
  4. 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

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


AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11). Data as JSON: /api/errors/b0a05b0654e16102. Report an issue: GitHub.