json-path/JsonPath · error · MappingException
JSON string cannot be mapped to " + className
Error message
JSON string cannot be mapped to " + className
What it means
JakartaMappingProvider.mapImpl throws this when the source JsonValue is a JsonString but the requested targetType is not String (and not char sequence types handled elsewhere). The provider performs no automatic string coercion, so a JSON string cannot be mapped to e.g. Integer or Boolean.
Source
Thrown at json-path/src/main/java/com/jayway/jsonpath/spi/mapper/JakartaMappingProvider.java:122
return Boolean.TRUE;
} else {
String className = targetType.toString();
throw new MappingException("JSON boolean (true) cannot be mapped to " + className);
}
}
if (source == JsonValue.FALSE) {
if (Boolean.class.equals(targetType)) {
return Boolean.FALSE;
} else {
String className = targetType.toString();
throw new MappingException("JSON boolean (false) cannot be mapped to " + className);
}
} else if (source instanceof JsonString) {
if (String.class.equals(targetType)) {
return ((JsonString) source).getChars();
} else {
String className = targetType.toString();
throw new MappingException("JSON string cannot be mapped to " + className);
}
} else if (source instanceof JsonNumber) {
JsonNumber jsonNumber = (JsonNumber) source;
if (jsonNumber.isIntegral()) {
return mapIntegralJsonNumber(jsonNumber, getRawClass(targetType));
} else {
return mapDecimalJsonNumber(jsonNumber, getRawClass(targetType));
}
}
if (source instanceof JsonArrayBuilder) {
source = ((JsonArrayBuilder) source).build();
} else if (source instanceof JsonObjectBuilder) {
source = ((JsonObjectBuilder) source).build();
}
if (source instanceof Collection) {
// this covers both List<JsonValue> and JsonArray from JSON-P spec
Class<?> rawTargetType = getRawClass(targetType);
Type targetTypeArg = getFirstTypeArgument(targetType);
View on GitHub (pinned to 62a4c9f0f6)
Solutions
- Request String.class and parse manually (Integer.parseInt, Boolean.parseBoolean)
- Correct the JSON path so it selects a non-string value of the expected type
- Use .map(...) with a custom converter that parses the string
- Switch to a lenient MappingProvider if implicit coercion is acceptable
Example fix
// before
int port = context.read("$.port", int.class); // "8080" -> MappingException
// after
int port = Integer.parseInt(context.read("$.port", String.class)); Defensive patterns
Strategy: type-guard
When it happens
Trigger: Calling read(path, SomeClass) where the JSON value at the path is a quoted string but the target class is not String — e.g. read("$.port", Integer.class) when the document contains "8080".
Common situations: Documents where numeric-looking values are quoted (IDs, ports); expecting automatic parse of "true"/"false" or "123" into primitives; migrating from a lenient mapping provider that coerced strings to numbers/booleans.
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
- JSON boolean (false) cannot be mapped to " + className
- JSON integral number cannot be mapped to " + className
- JSON decimal number cannot be mapped to " + className
- InvalidJsonException
- InvalidJsonException
AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11).
Data as JSON: /api/errors/9dd357e49c1c3867.
Report an issue: GitHub.