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.
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
-
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. -
Remove the validators if they were
redundant or wrong. If the source cells (
@countin the example) already have appropriate validators, the derived cell inherits "valid in the meaningful sense" from them — no per-derived gating needed. -
Reconsider the design if you really
wanted user-mutable. If the cell needs to BE user input,
it's not derived — drop the
constmodifier 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 .