{"record":{"id":"521e2cebf085f679","repo":"google/gson","slug":"missing-fieldname-field-at-path-path","errorCode":null,"errorMessage":"Missing ${fieldName} field; at path ${path}","messagePattern":"Missing (.+?) field; at path (.+?)","errorType":"exception","errorClass":"JsonSyntaxException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/bind/JavaTimeTypeAdapters.java","lineNumber":444,"sourceCode":"          } else if (rawType == ZoneId.class || rawType == ZoneOffset.class) {\n            // We don't check ZoneId.class.isAssignableFrom(rawType) because we don't want to match\n            // the non-public class ZoneRegion in the runtime type check in\n            // TypeAdapterRuntimeTypeWrapper.write. If we did, then our ZONE_ID would take\n            // precedence over a ZoneId adapter that the user might have registered. (This exact\n            // situation showed up in a Google-internal test.)\n            adapter = ZONE_ID;\n          } else if (rawType == ZonedDateTime.class) {\n            adapter = zonedDateTime(gson);\n          }\n          @SuppressWarnings(\"unchecked\")\n          TypeAdapter<T> result = (TypeAdapter<T>) adapter;\n          return result;\n        }\n      };\n\n  private static <T> T requireNonNullField(T field, String fieldName, JsonReader reader) {\n    if (field == null) {\n      throw new JsonSyntaxException(\n          \"Missing \" + fieldName + \" field; at path \" + reader.getPreviousPath());\n    }\n    return field;\n  }\n}\n","sourceCodeStart":426,"sourceCodeEnd":450,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/internal/bind/JavaTimeTypeAdapters.java#L426-L450","documentation":"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.","triggerScenarios":"Deserializing LocalDateTime from {\"time\":{...}} (missing 'date'), OffsetDateTime missing 'dateTime' or 'offset', OffsetTime missing 'time'/'offset', or ZonedDateTime missing any of 'dateTime'/'offset'/'zone'.","commonSituations":"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.","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."],"exampleFix":"// before: {\"time\":{\"hour\":10}}\nGson().fromJson(json, LocalDateTime::class.java) // Missing date field\n\n// after: include all required sub-objects\n{\"date\":{\"year\":2024,\"month\":1,\"day\":15},\"time\":{\"hour\":10,\"minute\":0,\"second\":0,\"nano\":0}}","handlingStrategy":"validation","validationCode":"// Validate required sub-fields for java.time composite types\nstatic boolean hasAll(String json, String... fields) {\n  JsonObject o = JsonParser.parseString(json).getAsJsonObject();\n  for (String f : fields) if (!o.has(f)) return false;\n  return true;\n}\n// e.g. LocalDateTime needs 'date' and 'time'\nif (!hasAll(json, \"date\", \"time\")) reject();","typeGuard":null,"tryCatchPattern":"try {\n  gson.fromJson(json, LocalDateTime.class);\n} catch (JsonSyntaxException e) {\n  if (e.getMessage().startsWith(\"Missing \") && e.getMessage().contains(\"field\")) {\n    // missing sub-object; default it or reject upstream\n    log.warn(\"Incomplete java.time payload: {}\", e.getMessage());\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["java-time","deserialization","schema","missing-field"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}