google/gson · error · JsonSyntaxException
Missing {fieldName} field; at path {path}
Error message
Missing {fieldName} field; at path {path} What it means
Thrown by JavaTimeTypeAdapters.requireNonNullField when a required subfield {fieldName} is absent while deserializing a composite java.time type. The composite adapters (LocalDateTime, OffsetDateTime, OffsetTime, ZonedDateTime) build the value from named sub-objects; if one of date/time/dateTime/offset/zone is missing the build cannot proceed. The {path} is the reader's previous path.
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 8b8628c656)
Solutions
- Make the producer emit all required subfields with the exact keys Gson expects (date/time for LocalDateTime; dateTime/offset for OffsetDateTime; dateTime/offset/zone for ZonedDateTime).
- Register a custom TypeAdapter for the java.time type that maps the producer's actual key names.
- If the value can legitimately be missing, model the field as nullable and have the producer send JSON null.
- Pre-scan the JSON object for the required keys and report a data-contract error to the producer.
Example fix
// before: '{"time":{"hour":10}}' -> Missing date field
// after: include all required sub-objects
String json = "{\"date\":{\"year\":2025,\"month\":1,\"day\":5},"
+ "\"time\":{\"hour\":10,\"minute\":0,\"second\":0,\"nano\":0}}";
LocalDateTime ldt = gson.fromJson(json, LocalDateTime.class); Defensive patterns
Strategy: validation
Validate before calling
// Pre-check composite java.time objects have required subfields
JsonObject o = JsonParser.parseString(json).getAsJsonObject();
if (!o.has("date") || !o.has("time")) {
throw new IllegalArgumentException("LocalDateTime JSON missing date or time");
} Try / catch
try {
return gson.fromJson(json, LocalDateTime.class);
} catch (JsonSyntaxException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Missing ") && e.getMessage().contains("field")) {
throw new InvalidPayloadException("Incomplete java.time JSON: " + e.getMessage(), e);
}
throw e;
} Prevention
- Ensure the producer emits all required subfields (or explicit null).
- Keep API versions aligned on the composite field layout.
- Write schema tests for the java.time JSON representation.
When it happens
Trigger: Deserializing a LocalDateTime whose JSON object has 'time' but no 'date'; an OffsetDateTime missing 'dateTime' or 'offset'; a ZonedDateTime missing 'dateTime', 'offset', or 'zone'. The producer omitted or misspelled one of the required keys.
Common situations: Producer trims null subfields; rename between API versions (e.g. 'localDateTime' vs 'dateTime'); partial deserialization of a log; client/server running different Gson versions that disagree on the field layout.
Related errors
- cannot deserialize {baseType} because it does not define a f
- Missing id or totalSeconds field; at path {path}
- cannot deserialize {baseType} subtype named {label}; did you
- Type adapter '{typeAdapter}' returned wrong type; requested
- JSON document was not fully consumed.
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/355bdb6c646a934b.json.
Report an issue: GitHub.