json-path/JsonPath · error · UnsupportedOperationException

JsonObject is immutable in JSON-P

Error message

JsonObject is immutable in JSON-P

What it means

JSON-P JsonObject is immutable, so JakartaJsonProvider.setProperty throws UnsupportedOperationException when the target is a plain JsonObject that is neither a JsonObjectBuilder nor (in mutableJson mode) a JsonObjectProxy. Setting properties on such objects is impossible without converting to a builder.

Source

Thrown at json-path/src/main/java/com/jayway/jsonpath/spi/json/JakartaJsonProvider.java:193

            JsonValue o = ((JsonObject) obj).get(key);
            if (o == null) {
                return UNDEFINED;
            } else {
                return unwrap(o);
            }
        } else {
            throw new UnsupportedOperationException();
        }
    }

    @Override
    public void setProperty(Object obj, Object key, Object value) {
        if (obj instanceof JsonObjectBuilder) {
            ((JsonObjectBuilder) obj).add(key.toString(), wrap(value));
        } else if (mutableJson && obj instanceof JsonObjectProxy) {
    		((JsonObjectProxy) obj).put(key.toString(), wrap(value));
    	} else if (obj instanceof JsonObject) {
    		throw new UnsupportedOperationException("JsonObject is immutable in JSON-P");
    	} else if (obj instanceof JsonArrayBuilder) {
    		if (key == null) {
    			((JsonArrayBuilder) obj).add(wrap(value));
    		} else {
				((JsonArrayBuilder) obj).set(toArrayIndex(key), wrap(value));
    		}
        } else if (mutableJson && obj instanceof JsonArrayProxy) {
        	if (key == null) {
    			((JsonArrayProxy) obj).add(wrap(value));
        	} else {
        		((JsonArrayProxy) obj).set(toArrayIndex(key), wrap(value));
    		}
    	} else if (obj instanceof JsonArray) {
    		throw new UnsupportedOperationException("JsonArray is immutable in JSON-P");
        } else if (obj instanceof List) {
        	@SuppressWarnings("unchecked")
        	List<JsonValue> array = (List<JsonValue>) obj;
        	if (key == null) {

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Enable mutableJson on the provider so documents are parsed into mutable proxies.
  2. Convert with Json.createObjectBuilder(jsonObject), mutate the builder, then build().
  3. Use a provider based on plain Maps (Jackson/Gson/JacksonJsonNodeJsonProvider) when mutation is required.

Example fix

// before
jsonPath.put(document, "newKey", value); // throws on immutable JsonObject
// after
JsonObjectBuilder b = Json.createObjectBuilder((JsonObject) document);
b.add("newKey", value);
document = b.build();
Defensive patterns

Strategy: type-guard

Type guard

// Java
static boolean isObjectMutable(Object o, boolean mutableJson) {
    return o instanceof JsonObjectBuilder || (mutableJson && o instanceof JsonObjectProxy);
}

Try / catch

try { provider.setProperty(obj, key, value); } catch (UnsupportedOperationException e) { obj = Json.createObjectBuilder((JsonObject) obj).add(key.toString(), value).build(); }

Prevention

When it happens

Trigger: JsonPath.put/set operations targeting an object member where the node is a JsonObject, mutableJson is false, and it is not a JsonObjectProxy.

Common situations: Attempting to add or overwrite fields in a JSON-P parsed document with the default (immutable) provider configuration.

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