Skip to content

Nested Schema Validation & Type mismatch check#729

Open
AbhinRustagi wants to merge 29 commits into
mainfrom
ar-schema-validation
Open

Nested Schema Validation & Type mismatch check#729
AbhinRustagi wants to merge 29 commits into
mainfrom
ar-schema-validation

Conversation

@AbhinRustagi

@AbhinRustagi AbhinRustagi commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

What this PR does

Previously the parser only checked that required top-level props were present — nested data was never validated, and a wrong-typed value flowed straight to the renderer. This PR adds recursive JSON-Schema validation of all component props (objects, arrays, scalar/enum leaves, and component elements in data positions), and applies one consistent resolution rule to every invalid value instead of either ignoring it or blanking the UI:

invalid value at an edge:
  1. schema has a `default`  →  substitute it (error still reported)
  2. edge is REQUIRED        →  parent becomes invalid; same rule one level up
  3. edge is OPTIONAL        →  prune the value
array items: always pruned  →  one bad row never takes down the table

At the outermost edge (component param), "propagate" means drop the component. Net effect: a deep violation can only blank the root if every edge on the path is required and none is an array item — i.e. only when the tree genuinely cannot satisfy the schema. LLM output degrades gracefully; the error always reaches the host's onError for the correction loop.

Cases covered

# Case Handling
Top-level args
1 Required arg, type/enum mismatch, default provided Substitute default, keep error
2 Required arg, type/enum mismatch, no default Drop component
3 Optional arg, mismatch, default provided Substitute default, keep error
4 Optional arg, mismatch, no default Drop the arg (prop pruned)
5 Required arg absent/null, default provided Fill silently, no error (pre-existing)
6 Required arg absent/null, no default Error + drop component (pre-existing)
7 Excess positional args Reported, extras dropped (pre-existing)
Nested objects
8 Required child key invalid, child has default Substitute child default; parent survives
9 Required child key invalid, no default Parent invalid → rule repeats one level up
10 Optional child key invalid, default provided Substitute default
11 Optional child key invalid, no default Prune the key; parent survives
12 Required child key absent/null, default provided Fill silently, no error
13 Required child key absent/null, no default Error (missing-required/null-required) + parent invalid
14 Wrong container kind (scalar/array where object expected, etc.) type-mismatch → resolution rule
Arrays
15 Any invalid item (bad type, missing required key, misplaced component) Item pruned, siblings kept — arrays never invalidate; error paths keep original indices
16 Non-array where array expected type-mismatch → resolution rule
Components in data positions
17 Element where a plain-data shape is declared (e.g. HorizontalBarChart(Card([]), …)) type-mismatch ("expects array but got component Card") → resolution rule
18 Element in a component slot ($ref/anyOf) Skipped — slot membership deferred (see below)
19 Misplaced component's own args Still validated independently; both errors surface
Streaming
20 Required-key checks mid-stream Deferred while partial; fire on completion
21 Enum membership mid-stream (e.g. Badge("prim cut mid-token) Deferred — a partial literal may still complete to a valid member; judged at completion
22 Scalar type checks mid-stream Active — a wrong scalar type can't become right by streaming more
Conservative skips (unchecked by design)
23 Composite schemas ($ref/anyOf/oneOf/allOf) for plain values Skipped
24 Dynamic values ($var, builtins) Skipped — resolve at runtime
25 Malformed schema fragments (unknown type, tuple items, non-array required) Skipped
26 Schema default values themselves Trusted, not validated

Deferred (explicit non-goals here)

  • $ref resolution — data behind $ref (e.g. chart Series) is still unchecked; biggest coverage gap, planned next.
  • Slot membership — "is this component allowed in this children slot" (helper existed, backed out to keep scope).
  • Per-statement streaming partial (checks currently gate on whole-document completeness); additionalProperties; constraint keywords (minItems, pattern, …).

@AbhinRustagi AbhinRustagi marked this pull request as ready for review July 9, 2026 04:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant