Skip to content

The exported schema ignores every serde alias: it declares invalid what the engine accepts #162

Description

@LeadcodeDev

Remaining item identified while closing round 4 of the audit. PR #161 fixed the background part of the exported schema (31 violations → 6); here is the cause of the remaining 6, and it is more general than expected.

The finding

rustmotion schema produces the file generators consume to know what to write. schemars does not emit #[serde(alias = ...)] — only the canonical name. Any document using an aliased spelling is therefore declared invalid by the schema while the engine accepts it perfectly.

Verified against the actually-exported schema:

"enum": ["float3d"]     ← present
"enum": ["float_3d"]    ← absent

AnimationPreset::Float3d carries #[serde(alias = "float_3d")]. The canonical spelling is float3d, and float_3d — the one the repository's own examples and documentation use — exists only as an alias, invisible to the schema.

Measured impact

Validating the repository's 8 examples against the schema exported by the CLI, with jsonschema (Draft 7):

File Failing paths
1600-style.json 2
dark-premium.json 2
mega-showcase.json 2

All trace back to 'float_3d' is not one of ['float3d'], propagated until the whole scene fails through SceneEntry's anyOf.

The full class

Ten serde(alias = ...) in the repository, all invisible to the exported schema:

File Unexposed aliases
schema/animation.rs:157, schema/video.rs:67 float_3d
schema/style.rs:23-46 flex-start, flex_start, flex-end, flex_end, space-between, space-around, space-evenly
css/style.rs:620-629 top_left, top_right, bottom_right, bottom_left (back-compat added by #161)
components/lib.rs:385 progress_bar
components/lib.rs:406 container

The last two deserve particular attention: CLAUDE.md explicitly documents div (alias for container) and lists progress among the components. A generator following the exported schema will never learn that container and progress_bar are accepted — and a tool validating against that schema will reject correct scenarios.

The schema/style.rs aliases are the most treacherous: flex-start and space-between are the actual CSS spelling. That is what an LLM writes spontaneously, and what the schema declares invalid.

Directions

  1. Hand-implement JsonSchema for the enums concerned, emitting the union {canonical} ∪ {aliases} in enum. PR fix(schema): turn the deserializer's silent sinks into named errors #161 did exactly this for BackgroundValue/BackgroundEntry, so the precedent exists in the repository.
  2. Or a shared macro/helper deriving the schema from the serde attributes, to avoid maintaining two lists by hand — which is the very failure mode this issue reports.

Option 1 is safer short-term; option 2 stops the problem recurring at the next alias added.

Verification

The 8 examples must validate against the output of rustmotion schema. Today: 5 of 8 (up from 2 of 8 before #161). An automated test already exists on the rustmotion-core side (crates/rustmotion-core/tests/exported_schema_examples.rs, added by #161) — extending it to the CLI's full schema would be the right net.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions