Skip to main content
FORGEJO ERA / ISSUE #601

Dataset validation does not mirror the checks the application applies on load

closedOpened by MelanX on

Original description​

By MelanX · October 23, 2026

Crate: ephervex-options (generated data) and tools/minecraft-options

Commit: 2b2af1e4f8166d02e4732d19e040a53745d97a51

Behavior

validate() is the pre-publication gate but does not enforce what crates/options/src/dataset.rs and codec.rs check on load, so the generator can publish a document that the application rejects wholesale. Missing checks:

  • codec well-formedness (min <= max, finite bounds, non-empty enums)
  • key validity (empty keys, : or control characters)
  • unsupported ids existing in the registry, and duplicate ids inside unsupported
  • duplicate schema ids and the type of data_version
  • table[position] is indexed before the range check, so a bad position raises IndexError and a negative one silently wraps

_AFFINE and _OFFSET accept [0-9.]+, so 1.2.3 or . match and float() raises an uncaught ValueError in representation_issue and codec_for.

Expected behavior

validate() rejects exactly what the application rejects, raising DatasetError for malformed positions and transform text.

Impact

A malformed dataset passes the gate, and clients silently keep their old data.

Locations

  • tools/minecraft-options/dataset.py validate (545-612), _AFFINE/_OFFSET (69-70), _number (80-84)
  • crates/options/src/dataset.rs, crates/options/src/codec.rs is_well_formed, crates/options/src/file.rs is_valid_key

Validation and limitations

Reproduced with a record whose integer codec has min 10 and max 2 and a key we:ird: validate() accepts it and the Rust loader would refuse it. Real data shows no violation today.