Skip to content

catalog.validate() silently strips on, repeat, watch, and state from specs #222

@rohanajayjain

Description

@rohanajayjain

Problem

When passing an AI-generated spec through catalog.validate(), the returned data is missing the on, repeat, watch fields from elements and state from the spec. This means a spec that renders correctly when used directly breaks completely after validation - event handlers, repeat lists, watchers, and initial state all disappear.

Minimal reproduction:

const spec = {
  root: "main",
  elements: {
    main: {
      type: "Button",
      props: { label: "Click me" },
      children: [],
      on: { press: { action: "setState", params: { statePath: "/count", value: 1 } } },
    },
  },
  state: { count: 0 },
};

const result = catalog.validate(spec);
// result.success === true
// result.data.elements.main.on === undefined  ← silently dropped
// result.data.state === undefined              ← silently dropped

No error is reported. The spec passes validation, but the validated output is broken.

Context

We're validating specs before persisting them to a database and want to make sure the AI output conforms to our catalog. This seemed like exactly what catalog.validate() is for, but it's actually destroying the data we're trying to protect.

I also noticed validateSpec() exists as a separate function that does structural checks (missing children, fields in the wrong place, etc.). It doesn't have the stripping problem because it operates on the Spec type directly.

Questions

  1. What's the intended validation story here? Should we be using catalog.validate(), validateSpec(), both, or something else? It's not clear from the docs how these relate to each other.

  2. Is the field omission intentional? I see that visible is declared in the React schema as s.any(), but on, repeat, watch, and state aren't declared at all. Is there a reason these were left out, e.g. a limitation of the schema builder, or is it just something that hasn't been addressed yet?

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