schemagen: absent additionalProperties is not rejected at generation (contradicts README) and silently rejects extra properties #55

Closed
opened 2026-07-19 15:35:04 +00:00 by weaselbot · 1 comment
Member

Summary

weaseljson-schemagen documents that an object schema with absent additionalProperties is "not supported (rejected at generation)", but the code does not reject it — it silently generates a strict parser that rejects documents containing any extra property. This is both a docs/code mismatch and a behavioral surprise for schemas written with standard JSON Schema conventions.

Documented contract

contrib/schemagen/README.md, "Schema -> C++ mapping" table (lines 47-48):

| `additionalProperties: false`                 | unknown keys rejected                  |
| `additionalProperties` absent / `true`        | not supported (rejected at generation) |

So absent additionalProperties is documented as rejected at generation time.

Actual behavior

contrib/schemagen/weaseljson_schemagen.py:420:

ap = node.get("additionalProperties", False)
if ap is True:
    raise GenError("additionalProperties: true is not supported")
if isinstance(ap, dict):
    raise GenError(
        "additionalProperties with a schema (typed map) is not " "supported yet"
    )

Only true (and a schema/typed-map value) are rejected. When additionalProperties is absent, node.get(...) returns False, the object is treated as strict, and generation succeeds.

Note the README is also internally inconsistent: the "Not supported (rejected at generation time)" prose section (contrib/schemagen/README.md:63-64) lists additionalProperties with a schema (typed map) and additionalProperties: true but does not list absent — consistent with the code, but contradicting the table on line 48.

Reproduction

Schema s.json (no additionalProperties):

{"type":"object","required":["x"],"properties":{"x":{"type":"integer"}}}
  1. Generate:
python3 contrib/schemagen/weaseljson_schemagen.py s.json -o gen.h --namespace sg
echo "exit=$?"

Observed: exit=0 — generation succeeds, despite the README saying this case is rejected at generation.

  1. Feed documents to the generated parser:
RootBuilder b1; feed(b1, R"({"x":1})");            // -> WeaselJson_OK, x == 1
RootBuilder b2; feed(b2, R"({"x":1,"extra":2})");  // -> WeaselJson_REJECT

Observed:

  • {"x":1} -> OK (x = 1)
  • {"x":1,"extra":2} -> REJECT

Expected vs actual

Per the README table, a schema without additionalProperties should fail generation. Instead it generates a strict parser. Per JSON Schema (draft 2020-12), absent additionalProperties means additional properties are allowed; the generated parser instead rejects any extra property. A schema author who omits additionalProperties (the common JSON Schema default) gets a parser that incorrectly rejects documents that are valid under their schema, with no indication in the README that absent is treated as strict.

Impact

  • Documentation does not match the code: the table claims a generation-time rejection that does not happen.
  • Schemas written with standard JSON-Schema conventions (omitting additionalProperties to allow extras) silently produce parsers that reject valid documents with extra properties.
  • The README is internally inconsistent about whether absent is supported.

Suggested fix

Either (a) make the code match the documented contract by raising GenError when additionalProperties is absent (forcing authors to specify false explicitly), or (b) correct the README table so absent is listed as "unknown keys rejected" (matching the code and the "Not supported" prose section) and document the JSON-Schema default divergence explicitly.

## Summary `weaseljson-schemagen` documents that an object schema with **absent** `additionalProperties` is *"not supported (rejected at generation)"*, but the code does not reject it — it silently generates a **strict** parser that rejects documents containing any extra property. This is both a docs/code mismatch and a behavioral surprise for schemas written with standard JSON Schema conventions. ## Documented contract `contrib/schemagen/README.md`, "Schema -> C++ mapping" table (lines 47-48): ``` | `additionalProperties: false` | unknown keys rejected | | `additionalProperties` absent / `true` | not supported (rejected at generation) | ``` So absent `additionalProperties` is documented as *rejected at generation time*. ## Actual behavior `contrib/schemagen/weaseljson_schemagen.py:420`: ```python ap = node.get("additionalProperties", False) if ap is True: raise GenError("additionalProperties: true is not supported") if isinstance(ap, dict): raise GenError( "additionalProperties with a schema (typed map) is not " "supported yet" ) ``` Only `true` (and a schema/typed-map value) are rejected. When `additionalProperties` is **absent**, `node.get(...)` returns `False`, the object is treated as strict, and generation succeeds. Note the README is also internally inconsistent: the "Not supported (rejected at generation time)" prose section (`contrib/schemagen/README.md:63-64`) lists `additionalProperties with a schema (typed map)` and `additionalProperties: true` but does **not** list `absent` — consistent with the code, but contradicting the table on line 48. ## Reproduction Schema `s.json` (no `additionalProperties`): ```json {"type":"object","required":["x"],"properties":{"x":{"type":"integer"}}} ``` 1. Generate: ```sh python3 contrib/schemagen/weaseljson_schemagen.py s.json -o gen.h --namespace sg echo "exit=$?" ``` Observed: `exit=0` — generation succeeds, despite the README saying this case is rejected at generation. 2. Feed documents to the generated parser: ```cpp RootBuilder b1; feed(b1, R"({"x":1})"); // -> WeaselJson_OK, x == 1 RootBuilder b2; feed(b2, R"({"x":1,"extra":2})"); // -> WeaselJson_REJECT ``` Observed: - `{"x":1}` -> `OK` (x = 1) - `{"x":1,"extra":2}` -> `REJECT` ## Expected vs actual Per the README table, a schema without `additionalProperties` should fail generation. Instead it generates a strict parser. Per JSON Schema (draft 2020-12), absent `additionalProperties` means additional properties are **allowed**; the generated parser instead **rejects** any extra property. A schema author who omits `additionalProperties` (the common JSON Schema default) gets a parser that incorrectly rejects documents that are valid under their schema, with no indication in the README that absent is treated as strict. ## Impact - Documentation does not match the code: the table claims a generation-time rejection that does not happen. - Schemas written with standard JSON-Schema conventions (omitting `additionalProperties` to allow extras) silently produce parsers that reject valid documents with extra properties. - The README is internally inconsistent about whether `absent` is supported. ## Suggested fix Either (a) make the code match the documented contract by raising `GenError` when `additionalProperties` is absent (forcing authors to specify `false` explicitly), or (b) correct the README table so `absent` is listed as "unknown keys rejected" (matching the code and the "Not supported" prose section) and document the JSON-Schema default divergence explicitly.
weaselbot changed title from schemagen: absent is not rejected at generation (contradicts README) and silently rejects extra properties to schemagen: absent `additionalProperties` is not rejected at generation (contradicts README) and silently rejects extra properties 2026-07-19 15:35:22 +00:00
Owner

Reject unless additionalProperties is set to false explicitly, with a nice error message

Reject unless additionalProperties is set to false explicitly, with a nice error message
weaselbot was assigned by andrew 2026-07-20 01:09:43 +00:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: weaselab/weaseljson#55