scrml.dev v0.7.1
Reference › Errors

E-DERIVED-WITH-VALIDATORS

Validators applied to a derived (const) cell. Derived cells are read-only; validators imply gating which is incoherent on a computed value.

Error Compile-time SPEC §55.14 (normative)

What it means

Validators (the universal-core predicate vocabulary req / length / pattern / min / max / etc. per SPEC §55.1) describe constraints on a state cell's value with the assumption that the value WILL change — the validity surface ( @cell.isValid, @cell.errors) transitions as the cell mutates.

Derived cells ( const <x> = expr) are read-only by definition — their value is recomputed from dependency cells, never assigned directly. Applying validators to a derived cell would either gate a value the user can't change (incoherent), or invite mutation of a cell that shouldn't be mutated (a contradiction with the cell's read-only contract).

Minimal reproducer

<form>
  <name> = <input type="text"/>
  <count req min(0)> = 0
  const <doubled req min(0)> = @count * 2
  //              ^^^^^^^^^^
  //              E-DERIVED-WITH-VALIDATORS: validators on a const cell.
</>

How to fix

  1. Use a refinement type instead. The canonical fix — constrain the TYPE rather than gate the VALUE. The refinement-type form is const <doubled>: number(min(0)) = @count * 2. The predicate becomes part of the type contract; if the derived expression ever yields a value violating the refinement, a different error fires (E-TYPE-* family) pinned to the COMPUTATION, not to a gate on the result.
  2. Remove the validators if they were redundant or wrong. If the source cells ( @count in the example) already have appropriate validators, the derived cell inherits "valid in the meaningful sense" from them — no per-derived gating needed.
  3. Reconsider the design if you really wanted user-mutable. If the cell needs to BE user input, it's not derived — drop the const modifier and make it a plain reactive cell that the user writes to.

Validators vs refinement types

scrml ships the same predicate vocabulary in two native loci:

  • State-cell validators (§55.2) — bareword attributes on a writable cell decl. Compile to runtime gates that fire on writes; populate the auto-synthesized validity surface.
  • Refinement-type predicates (§53.6) — same vocabulary as part of a type annotation. Compile to compile-time + runtime checks at expression positions. Apply to any cell with a type annotation, INCLUDING derived cells.

E-DERIVED-WITH-VALIDATORS surfaces when the developer reached for the first locus (state-cell validator) on a derived cell; the second locus (refinement type) is the right tool.

Related

  • E-SYNTHESIZED-WRITE — companion error for writes to auto-synthesized validity properties.
  • <errors> — first-class element for rendering the validity surface.

Specification

Normative text: SPEC §55.14 (validators on derived cells forbidden + refinement-type cross-ref), §53.6 (refinement-type predicate vocabulary), §55.1 (universal-core predicate catalog), §34 catalog row. Spec lives at compiler/SPEC.md .