Skip to content

Evaluation Faults

Static validation rejects everything that is knowable before a run starts. It cannot know every value. An evaluation that cannot produce a value at run time is an evaluation fault:

  • division or modulo by zero;
  • an integer result outside the int range, or an operation that would produce NaN or an infinity;
  • an arithmetic operator applied to a value that is not a number, % applied to a value that is not an int, or not, and, or or applied to a value that is not a boolean;
  • an ordered comparison whose operands are not two values of one ordered type, including a comparison against null;
  • an ordering filter applied to a collection that mixes ordered types;
  • in whose right operand is not a list, a map, or a string;
  • a conversion filter applied to a value that it cannot convert unambiguously, such as int on "n/a";
  • a filter applied outside its declared signature, where the input’s type could not be established statically, as with a value typed json;
  • a filter argument that is invalid at run time and was not a literal. A computed format string with the wrong arity, and a computed matches pattern that is not valid RE2, are both of this kind;
  • a guard that yields a value that is not a boolean, where the type could not be established statically.

Faults are deterministic. By purity, evaluation depends only on the bindings in scope, so a faulting expression faults identically on every re-evaluation and on every conforming implementation. Its handling follows from that:

  • A fault in a step’s arguments, or in a value step, fails that step. Implementations MUST classify the failure as fatal, and MUST NOT retry it, because re-evaluation cannot succeed. It is otherwise an ordinary step failure: optional records it and continues, scope recovery observes it, and must_succeed blocks on it.
  • A fault in a guard position fails the guarded step or construct. Implementations MUST NOT read it as false. Implementations MUST NOT record it as a skip, because a skip records a decision and a fault is the absence of one.
  • A fault in a trigger’s when or queue_by prevents the run from starting.
  • Implementations MUST record a fault as they record any other outcome, and MUST replay it as a fault.

Every fault condition has a code in the error code registry, as every condition of static validation does.