Validation Panel
The right-side Issues panel that surfaces dangling block references, the per-block dot badge, and the deploy gate.
The Validation panel is the right-side Issues drawer in the workflow editor. It surfaces problems that won't necessarily crash a workflow but will silently misbehave at run time — most commonly, dangling block references like <api1.foo> typed before api1 exists or after it has been deleted.
The same validation result powers two other surfaces: a per-block dot badge on the canvas (warning + error counts) and a deploy gate that can block Deploy API when error-severity issues are present.
What the validator checks
The validator is implemented in apps/sat/lib/workflow-validation/reference-validator.ts. It runs at save time and on every block-graph mutation.
Today it has one rule:
- Dangling block references — every subBlock string value is scanned for
<blockName.path>references. A reference is dangling ifblockNamedoes not match any block in the workflow (after name normalization) and is not a system prefix (start,loop,parallel,variable) or a trigger alias (api,chat,manual,webhook,schedule).
The result type is plumbed through with a severity: 'warning' | 'error' field so future rules (cyclic deps, type mismatches, missing required credentials) can produce blocking issues without changing the response shape. Today every issue ships at 'warning'.
Issue shape
interface ValidationIssue {
blockId: string // ID of the block that contains the bad reference
blockName: string // Human-readable name shown in the panel
subBlockId?: string // SubBlock id where the reference was found
severity: 'warning' | 'error'
referencedPath: string // Raw reference, e.g. <api1.notarealfield>
reason: string // Short user-facing explanation
}Deploy gate
apps/sat/lib/workflow-validation/deploy-gate.ts determines whether a workflow can be deployed given its current set of issues:
- Zero issues → deploy proceeds.
- Only warnings → deploy proceeds (validator only emits warnings today).
- Any error-severity issue → Deploy API is disabled with the message
Cannot deploy — fix N validation error(s) first.
When future rules emit 'error' severity, no UI changes are needed — the deploy button picks up the gate signal automatically.
Surfaces
| Surface | What it shows |
|---|---|
| Issues panel (right rail) | Full list grouped by source block; click an item to focus the offending subBlock. |
| Per-block dot badge | Small colored dot on the block card. Yellow = warnings, red = errors, none = clean. |
| Deploy button | Disabled when canDeploy() returns ok: false; tooltip explains the blocker count. |
The dot-badge selector was the reference incident for Pattern G in the incident skill — Zustand selectors that return a freshly-allocated collection cause React #185 ("Maximum update depth exceeded"). The current implementation subscribes to a primitive (some() / length) per block; do not regress to a filter() selector in the badge component.
Surfacing your own validation rules
Add a new function alongside validateReferences() in reference-validator.ts that returns ValidationIssue[]. Compose them in the editor's validation hook. Use severity: 'error' only when the rule is unambiguous (dangling refs, broken cyclic deps); reserve 'warning' for "probably wrong but not always."