json-path/JsonPath · error · JsonException

Cannot create JSON iterator for " + value

Error message

Cannot create JSON iterator for " + value

What it means

createScope() in JakartaMappingProvider's JsonStructureToParserAdapter can only iterate JsonArray and JsonObject structures. If it is handed any other JsonValue (a scalar like JsonString, JsonNumber, JsonValue.TRUE/FALSE/NULL), it throws JsonException because no container iterator exists for scalars. This is called by the adapter constructor and by next() when advancing into nested values.

Source

Thrown at json-path/src/main/java/com/jayway/jsonpath/spi/mapper/JakartaMappingProvider.java:545

                while (scope.hasNext()) {
                    scope.next();
                }
                state = Event.END_OBJECT;
            }
        }

        @Override
        public void close() {
            // JSON objects are read-only
        }

        private JsonStructureScope createScope(JsonValue value) {
            if (value instanceof JsonArray) {
                return new JsonArrayScope((JsonArray) value);
            } else if (value instanceof JsonObject) {
                return new JsonObjectScope((JsonObject) value);
            }
            throw new JsonException("Cannot create JSON iterator for " + value);
        }

        private Event getState(JsonValue value) {
            switch (value.getValueType()) {
            case ARRAY:
                return Event.START_ARRAY;
            case OBJECT:
                return Event.START_OBJECT;
            case STRING:
                return Event.VALUE_STRING;
            case NUMBER:
                return Event.VALUE_NUMBER;
            case TRUE:
                return Event.VALUE_TRUE;
            case FALSE:
                return Event.VALUE_FALSE;
            case NULL:
                return Event.VALUE_NULL;

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Wrap or normalize scalars before mapping — ensure the value passed to map/toJson is a JsonObject or JsonArray
  2. Refine the JsonPath so it returns a structure, or read scalar results directly instead of via the streaming adapter
  3. Catch JsonException and handle scalar results as leaf values in your code

Example fix

// before
Object doc = Json.createObjectBuilder().build();
JsonValue scalar = jsonPath.read(doc); // may be a JsonString
mapper.map(scalar, ...); // JsonException
// after
JsonValue scalar = jsonPath.read(doc);
if (scalar instanceof JsonStructure) {
    mapper.map(scalar, ...);
} else {
    Object v = unwrapScalar(scalar); // handle string/number/bool/null directly
}
Defensive patterns

Strategy: validation

Validate before calling

if (!(value instanceof JsonStructure)) {
    throw new IllegalArgumentException("Expected JsonObject or JsonArray, got: " + value.getValueType());
}

Type guard

boolean isIterableStructure(JsonValue v) {
    return v instanceof JsonArray || v instanceof JsonObject;
}

Try / catch

try {
    mapper.map(value, typeRef, config);
} catch (JsonException e) {
    // value was a scalar; unwrap or wrap it before mapping
}

Prevention

When it happens

Trigger: Driving the adapter with a root or nested JsonValue that is a scalar (string, number, true, false, null) rather than a JsonObject or JsonArray — e.g. mapping the result of a JSON-P query that selected a single scalar.

Common situations: A JsonPath expression like $.name or $[0] that resolves to a scalar is fed to the Jakarta mapping provider, which expects a JSON structure at the root; upgrading providers so a previously object/array root is now scalar.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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