schemagen silently dropped any required entry without a matching key in properties. Since additionalProperties: false is mandatory and rejects every key not listed in properties, such a schema is unsatisfiable — yet generation succeeded and the emitted parser had no seen bit for the dangling key, so documents missing it were accepted (requiredMask = { 0x0u }), contradicting the README contract ("missing required property (top-level or nested)" is rejected at parse time).
Following the pattern established by #55/#58, this rejects such schemas at generation time with a GenError — there is no correct parse-time fallback since the schema can never match any document.
Changes
contrib/schemagen/weaseljson_schemagen.py: in _build_object(), raise GenError when set(required) is not a subset of properties.keys(). Applies to root, nested, and $defs object schemas alike (single object build path). Message: required key 'b' has no matching properties entry (plural form when several keys are affected).
contrib/schemagen/README.md: list required entries with no matching properties key in the "Not supported (rejected at generation time, no fallback)" section.
contrib/schemagen/test_schemagen.py: new SchemagenRequiredPropertyTest covering the issue reproduction, multiple dangling keys, an object schema with required but no properties, and a nested $defs object; plus a positive control that a matching required key still generates.
Testing
python3 contrib/schemagen/test_schemagen.py: 28/28 pass (pre-commit black hook passes).
Full cmake && make && ctest: 26/26 pass, including schemagen_example, schemagen_big, schemagen_nullable_root.
## Summary
`schemagen` silently dropped any `required` entry without a matching key in `properties`. Since `additionalProperties: false` is mandatory and rejects every key not listed in `properties`, such a schema is unsatisfiable — yet generation succeeded and the emitted parser had no seen bit for the dangling key, so documents missing it were accepted (`requiredMask` = `{ 0x0u }`), contradicting the README contract ("missing required property (top-level or nested)" is rejected at parse time).
Following the pattern established by #55/#58, this rejects such schemas at generation time with a `GenError` — there is no correct parse-time fallback since the schema can never match any document.
## Changes
- `contrib/schemagen/weaseljson_schemagen.py`: in `_build_object()`, raise `GenError` when `set(required)` is not a subset of `properties.keys()`. Applies to root, nested, and `$defs` object schemas alike (single object build path). Message: `required key 'b' has no matching properties entry` (plural form when several keys are affected).
- `contrib/schemagen/README.md`: list `required` entries with no matching `properties` key in the "Not supported (rejected at generation time, no fallback)" section.
- `contrib/schemagen/test_schemagen.py`: new `SchemagenRequiredPropertyTest` covering the issue reproduction, multiple dangling keys, an object schema with `required` but no `properties`, and a nested `$defs` object; plus a positive control that a matching required key still generates.
## Testing
- `python3 contrib/schemagen/test_schemagen.py`: 28/28 pass (pre-commit `black` hook passes).
- Full `cmake && make && ctest`: 26/26 pass, including `schemagen_example`, `schemagen_big`, `schemagen_nullable_root`.
Closes #63
A `required` entry without a matching `properties` key made the schema
unsatisfiable: additionalProperties: false (the only supported object
mode) rejects any key not listed in `properties`, so the required key
can never be present. Since no seen bit is emitted for such keys, the
generated parser silently accepted every document instead of rejecting
them as the README contract requires ("missing required property").
Follow the pattern from issue #55 and raise GenError at generation time
when set(required) is not a subset of properties.keys(), for root,
nested, and $defs object schemas alike. Update the README's
not-supported list accordingly.
Closes#63
andrew
merged commit 730a4cd0f6 into main2026-08-31 17:44:05 +00:00
andrew
deleted branch weaselbot/issue-632026-08-31 17:44:06 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
schemagensilently dropped anyrequiredentry without a matching key inproperties. SinceadditionalProperties: falseis mandatory and rejects every key not listed inproperties, such a schema is unsatisfiable — yet generation succeeded and the emitted parser had no seen bit for the dangling key, so documents missing it were accepted (requiredMask={ 0x0u }), contradicting the README contract ("missing required property (top-level or nested)" is rejected at parse time).Following the pattern established by #55/#58, this rejects such schemas at generation time with a
GenError— there is no correct parse-time fallback since the schema can never match any document.Changes
contrib/schemagen/weaseljson_schemagen.py: in_build_object(), raiseGenErrorwhenset(required)is not a subset ofproperties.keys(). Applies to root, nested, and$defsobject schemas alike (single object build path). Message:required key 'b' has no matching properties entry(plural form when several keys are affected).contrib/schemagen/README.md: listrequiredentries with no matchingpropertieskey in the "Not supported (rejected at generation time, no fallback)" section.contrib/schemagen/test_schemagen.py: newSchemagenRequiredPropertyTestcovering the issue reproduction, multiple dangling keys, an object schema withrequiredbut noproperties, and a nested$defsobject; plus a positive control that a matching required key still generates.Testing
python3 contrib/schemagen/test_schemagen.py: 28/28 pass (pre-commitblackhook passes).cmake && make && ctest: 26/26 pass, includingschemagen_example,schemagen_big,schemagen_nullable_root.Closes #63
A `required` entry without a matching `properties` key made the schema unsatisfiable: additionalProperties: false (the only supported object mode) rejects any key not listed in `properties`, so the required key can never be present. Since no seen bit is emitted for such keys, the generated parser silently accepted every document instead of rejecting them as the README contract requires ("missing required property"). Follow the pattern from issue #55 and raise GenError at generation time when set(required) is not a subset of properties.keys(), for root, nested, and $defs object schemas alike. Update the README's not-supported list accordingly. Closes #63