Skip to content

Alternate Names keywords are effectively unvalidated: altenums and descriptions in no SDK, altnames in only two #183

Description

@clemensv

A schema may declare "$uses": ["JSONStructureAlternateNames"] and then put almost anything under altenums or descriptions without a validator objecting. The keywords are recognised as belonging to a known extension, and then not checked.

Repro

All against json-structure-check --extended from the Python SDK, with "JSONStructureAlternateNames" present in $uses.

Schema fragment Spec says Result
"altenums": "not-an-object" MUST be a JSON object Schema is valid.
"altenums": {...} on a schema with no enum "MUST be used only with schemas that include an enum keyword" Schema is valid.
"altenums": {"lang:en": {"notAnEnumValue": "x"}} keys map "each enumeration value (as defined in the enum array)" Schema is valid.
"altnames": {"lang:en": 12345} values are alternate name strings Schema is valid.

altenums with the extension absent from $uses is also accepted, which is a separate question but the same root cause.

For contrast, a name in $uses that no extension defines is rejected:

 - #/$uses[1] [SCHEMA_USES_UNKNOWN_EXTENSION] Unknown extension 'TotallyBogusFeatureName' in $uses.

So the extension is known to the implementation; its keywords are simply not validated.

State of the code

  • altenums appears in no SDK's validator source. Searching the repository finds it only in python/tests/test_instance_validator.py, in a test that asserts an instance validates while the keyword is ignored.
  • descriptions is likewise unvalidated.
  • altnames has error codes defined in nine languages — SCHEMA_ALTNAMES_NOT_OBJECT and SCHEMA_ALTNAMES_VALUE_NOT_STRING, exported from each language's public error-code surface, and described in assets/error-messages.json — but only two implementations ever raise them: java/.../SchemaValidator.java (validateAltnames) and perl/lib/JSON/Structure/SchemaValidator.pm. In .NET, Go, PHP, Python, Rust, Swift, and TypeScript the constants are defined and dead.

That last point is the one I would fix first: seven SDKs publish an error code they can never emit, which is a stronger signal of intent than an absent feature would be.

Why it matters

The gap is easy to hit and silent. I annotated thirty-seven enums across a sample corpus and had to write a separate checker script to find the mistakes I made while doing it — wrong symbol keys, a missing entry, an empty label. The SDK reported every one of those schemas as valid.

Proposal

Implement schema-time validation for the Alternate Names keywords, in the shared rule set so that all languages get it:

  • altnames — object; every value a non-empty string. (Port the Java implementation.)
  • descriptions — object; every value a non-empty string.
  • altenums — object; every value an object; every value of that inner object a non-empty string; the enclosing schema has an enum; the inner object's keys are enum values.

The last two of those depend on questions the Alternate Names draft does not currently answer — how a non-string enum value is written as a mapping key, and whether a mapping may be partial. I have opened those separately against json-structure/alternate-names; the key-form check should follow whatever is decided there. The first three checks do not depend on anything and could land now.

Whatever lands, please add the negative cases to test-assets/ so the implementations converge rather than each inventing a subset.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions