vercel-labs / vercel-labs/json-render

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

Open
#222 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
16.8k
Forks
901
Avg merge
3h 14m
Merged PRs (30d)
4

Description

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?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the minimal example with catalog.validate(), then compare its schema declarations with validateSpec() and the React schema, especially the handling of on, repeat, watch, state, and visible. The work is done when the intended validation path is established and the relevant fields are preserved or their omission is explicitly documented, with coverage for the reported case.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.