Skip to main content

Overview

Every time you change a model, ProDex re-checks it, together with the schedule you have selected, against a set of correctness rules. The result shows on the play button at the bottom of the canvas: While a model first loads and is checked, the button is grey (“Validating model…”). If the check itself couldn’t complete, the button turns red with the tooltip “Validation check failed — click to retry.” Because validation runs on every change, you catch problems as you introduce them rather than discovering them when a simulation fails.

Reading the Popover

Hover a red or amber play button to open a popover with:
  • A header counting the problems, such as “1 validation error” or “3 validation warnings”. When errors and warnings both exist, the popover lists only the errors.
  • The error or warning text, naming the component and what’s wrong with it. A long list ends with a line such as ”… and 4 more validation errors omitted.”
  • A Fix with Dexter button.
A real example of an error:
“Component ‘Halo Repress Halo Queue’ (type: BufferDefinition) must have exactly one outgoing standard connection, but has 2. To split flow across multiple destinations (pass/fail, rework, triage), keep a single connection into a Router and branch there — a Router is the only flow component that takes multiple outgoing connections.”

Fix with Dexter

Fix with Dexter opens Dexter and sends it the listed errors (or warnings) with the request to read and resolve them. Dexter then edits the model directly; there’s no separate approval step for its changes, so look over the canvas when it’s done. The button is unavailable while Dexter is busy with another request. If you’d rather fix it yourself, the message is specific enough to point you at the component, field, or expression to edit.

Errors vs. Warnings

  • Errors block simulation. The button stays red until every error is resolved.
  • Warnings never block a run. They flag models that are legal but likely to misbehave.
The warnings you can see today:
  • Zero-delay cycle: a routing loop with no step that takes time, which can stall the simulation clock if entities enter it
  • Hold-and-wait cycle: entities holding resources across processes in a way that can deadlock
  • A Resource whose capacity (or a set capacity action’s target) is above 10,000, which the run will reject
  • A probabilistic Router whose weights are all zero or negative, so every entity takes the last option
  • A schedule that releases very large bursts at a single instant, or whose releases and scheduled actions fire so often that the run will be slow

What Blocks a Run

The rules below produce errors. Each error message names the component involved.

Connections

  • Source: no incoming connections, exactly one outgoing
  • Sink: no outgoing connections
  • Router and ModelNode: at least one outgoing connection
  • Process, Buffer, Combiner, Separator, Transformer: exactly one outgoing connection. To split flow, connect to a Router and branch there.
  • Connections join components, not Stations.
Every component must also be reachable from a Source through some chain of connections.
Flow loops are allowed. Routing entities back through an upstream Process (a rework loop) is valid. Only event-driven loops are errors (see Event Hooks and Topics).

Unused Resources and Stations

  • A Resource that no component uses is an error: “Resource ’…’ is defined but never used.” Require it on a Process, or delete it.
  • A Station that no component is assigned to is an error. Assign it on the components that operate there, or delete it.
Every resource or station a component refers to must also exist.

Entity Flow

  • Every component’s expected input entity types must actually arrive from upstream, and no component may receive a type it doesn’t expect.
  • Sources, schedules, and other generators can only create entity types that exist.

Attribute Assignment

Each attribute assignment’s Strategy must suit the attribute’s type (for example, Distribution only works for Number attributes), and fixed or weighted values must be valid for the attribute. Assignments must also refer to attributes that exist on the entity type. See Entities for which strategies each type allows.

Routers

A conditional Router needs a default route for entities that match no rule, and every connection a Router’s rules or routes refer to must start at that Router. A probabilistic Router needs at least one option, and a type-based Router can’t have outgoing connections that none of its routes use.

Expressions

The expression language is statically typed, so every expression is checked here rather than failing mid-run:
  • Conditions must produce booleans; numeric fields must produce numbers
  • Aggregations such as SUM or ANY only work where several entities are in scope
  • Every name must resolve in the expression’s context. An entity attribute used where no entity is in scope, a misspelled name, or a constant the model hasn’t added all fail with “Unknown identifier ’…’”
See Expression Contexts when an identifier you expected to work is reported as unknown.

Names

  • Component ids must be unique within the model
  • Constants and lookup tables and state variables must have SCREAMING_SNAKE_CASE names that don’t clash with reserved words or with each other
  • A state variable’s initial value must match its type
  • Lookup table entries must match their key columns and value type

Event Hooks and Topics

  • Hooks must use events that exist for their component type
  • Actions must be valid for the component they’re on
  • Every topic must be both emitted and listened to
  • Two direct loops are forbidden: a Source’s entity created hook releasing from that Source, and a Buffer’s entity exited hook releasing from that Buffer
See Event System.

Schedule

The selected schedule is checked together with the model:
  • End Time must be after Start Time
  • Material releases must target a Source or Buffer that exists and can accept the released entity type
  • Scheduled actions must fall between the schedule’s start and end
A Start Time without a timezone is treated as UTC.

Run Length

A run can’t be longer than 2 years, whether the length comes from the model’s duration or from the schedule’s Start and End Times.

Sub-models

Validation also checks every sub-model placed on the canvas. An error inside one is reported with a prefix naming the sub-model and the ModelNode that uses it, such as “Nested model ‘cell_a’ (used by model node ‘fab_cell’): …”

What Validation Does NOT Catch

Validation catches structural and type-level problems. Some things slip through:
  • Semantic correctness. A model that runs may still encode wrong assumptions about your operation. Validation can’t tell you a 30-second process should really be 30 minutes.
  • Distribution parameters. The play button doesn’t check that a distribution’s parameters are legal (for example, a Triangular mode outside its bounds). The run corrects such values and reports a runtime advisory; see Distributions. It also doesn’t judge whether a distribution fits your data.
  • Runtime arithmetic. A division by zero or a value that isn’t a number is set to 0 during the run and reported as a runtime advisory.
  • Resource starvation. A model where a critical resource is held forever by a stuck entity validates fine but produces meaningless results. Read the run’s results to catch these.
  • Comparison design. Validation looks at one model; it doesn’t judge whether you’re comparing the right runs.
  • Performance. A valid model can still take a long time to run. Use short durations while you iterate.
When a run finishes with runtime advisories, a toast says so (“Run completed with 2 runtime advisories — results may be affected”). Check them before trusting the results.

Validation and Dexter

Changes Dexter makes are checked by the same rules, plus a few extra checks on Dexter’s side, such as distribution parameters. Dexter sees the resulting errors and warnings after each edit. An edit that leaves errors turns the play button red just like one of yours. If Dexter repeatedly fails to fix something, read the errors yourself: often the fix needs a fact Dexter couldn’t infer (a missing constant, an attribute name that doesn’t exist on the entity type), and telling Dexter that fact unblocks it.

Tips

  • Fix connection errors first. Disconnected-component errors often hide expression errors that can’t be checked until the structure is sound.
  • Read the warnings, not just the errors. An amber button still runs, but a zero-delay cycle or a hold-and-wait cycle is how a model ends up stalling instead of failing fast.
  • The error messages are specific. If one is confusing, search the docs for its key phrase: most errors map directly to a concept covered in this reference.
  • Treat the red button as information. It stops you from waiting on a simulation that was going to fail.