JsonContentHandler.isNestedBeneathMissingOptionalField decides whether a missing descriptor is covered by an absent optional ancestor using a plain string prefix test:
if (candidate.isOptional() && descriptor.getPath().startsWith(candidate.getPath()) && isMissing(candidate, payload)) {
Because there is no segment-boundary check, a required field whose path merely shares a string prefix with an absent optional field's path is treated as nested beneath it, and its absence is never reported. For payload {"c": "charlie"} with descriptors optional a (absent) and required ab (absent), findMissingFields() returns nothing and the snippet is generated, although ab is a missing required field. The same applies to e.g. optional a.b and required a.bc, and it also affects resolveFieldType.
Reproduced on main (3ec9c63, 4.0.2-SNAPSHOT).
Expected: ab is only considered nested beneath a when the path continues with a segment boundary (a.b... or a[...]), so the missing required field is reported. I will submit a PR with a fix and tests.
JsonContentHandler.isNestedBeneathMissingOptionalFielddecides whether a missing descriptor is covered by an absent optional ancestor using a plain string prefix test:Because there is no segment-boundary check, a required field whose path merely shares a string prefix with an absent optional field's path is treated as nested beneath it, and its absence is never reported. For payload
{"c": "charlie"}with descriptors optionala(absent) and requiredab(absent),findMissingFields()returns nothing and the snippet is generated, althoughabis a missing required field. The same applies to e.g. optionala.band requireda.bc, and it also affectsresolveFieldType.Reproduced on
main(3ec9c63, 4.0.2-SNAPSHOT).Expected:
abis only considered nested beneathawhen the path continues with a segment boundary (a.b...ora[...]), so the missing required field is reported. I will submit a PR with a fix and tests.