google/gson · error · JsonSyntaxException
Missing field; at path
Error message
Missing ${fieldName} field; at path ${path} What it means
Composite java.time adapters (LocalDateTime, OffsetDateTime, OffsetTime, ZonedDateTime) call requireNonNullField for each mandatory sub-component; if a required member ('date', 'time', 'dateTime', 'offset', or 'zone') is absent in the JSON object, this JsonSyntaxException is thrown naming the missing field.
Solutions
- Make the producer emit all required sub-objects (even when null, emit proper null/empty objects).
- Register a custom TypeAdapter for the java.time type that tolerates missing fields with sensible defaults.
- Pre-validate the JSON object's keys before deserialization.
- If migrating formats, serialize then re-deserialize with the same Gson to confirm round-trip compatibility.
Example fix
// before: {"time":{"hour":10}}
Gson().fromJson(json, LocalDateTime::class.java) // Missing date field
// after: include all required sub-objects
{"date":{"year":2024,"month":1,"day":15},"time":{"hour":10,"minute":0,"second":0,"nano":0}} Defensive patterns
Strategy: validation
Validate before calling
// Validate required sub-fields for java.time composite types
static boolean hasAll(String json, String... fields) {
JsonObject o = JsonParser.parseString(json).getAsJsonObject();
for (String f : fields) if (!o.has(f)) return false;
return true;
}
// e.g. LocalDateTime needs 'date' and 'time'
if (!hasAll(json, "date", "time")) reject(); Try / catch
try {
gson.fromJson(json, LocalDateTime.class);
} catch (JsonSyntaxException e) {
if (e.getMessage().startsWith("Missing ") && e.getMessage().contains("field")) {
// missing sub-object; default it or reject upstream
log.warn("Incomplete java.time payload: {}", e.getMessage());
}
throw e;
} Prevention
- Ensure producers emit all required sub-objects (date/time/offset/zone) even when null.
- Register a tolerant custom adapter with sensible defaults.
- Add schema tests for java.time payloads.
- Round-trip test: serialize then deserialize to confirm compatibility.
When it happens
Trigger: Deserializing LocalDateTime from {"time":{...}} (missing 'date'), OffsetDateTime missing 'dateTime' or 'offset', OffsetTime missing 'time'/'offset', or ZonedDateTime missing any of 'dateTime'/'offset'/'zone'.
Common situations: Partial payloads from producers that omit null sub-objects; renaming fields on the producer side; schema drift after a Gson or JDK upgrade that changed the encoding.
Related errors
- Missing id or totalSeconds field; at path
- Array must have size 1, but has size
- Attempted to deserialize a java.lang.Class. Forgot to…
- Cannot allocate . Usage of JDK sun.misc.Unsafe is enabled…
- cannot deserialize because it does not define a field named
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/521e2cebf085f679.
Report an issue: GitHub.
Appendix: source
Thrown at gson/src/main/java/com/google/gson/internal/bind/JavaTimeTypeAdapters.java:444
} else if (rawType == ZoneId.class || rawType == ZoneOffset.class) {
// We don't check ZoneId.class.isAssignableFrom(rawType) because we don't want to match
// the non-public class ZoneRegion in the runtime type check in
// TypeAdapterRuntimeTypeWrapper.write. If we did, then our ZONE_ID would take
// precedence over a ZoneId adapter that the user might have registered. (This exact
// situation showed up in a Google-internal test.)
adapter = ZONE_ID;
} else if (rawType == ZonedDateTime.class) {
adapter = zonedDateTime(gson);
}
@SuppressWarnings("unchecked")
TypeAdapter<T> result = (TypeAdapter<T>) adapter;
return result;
}
};
private static <T> T requireNonNullField(T field, String fieldName, JsonReader reader) {
if (field == null) {
throw new JsonSyntaxException(
"Missing " + fieldName + " field; at path " + reader.getPreviousPath());
}
return field;
}
}
View on GitHub (pinned to 310ac341f2)