Workflow Validator (opt-in, S14.2)
A pre-flight check that lives inside your graph
- validation_report
OldTimeRadio is a pack written by someone who got tired of workflows breaking silently, and OTR_WorkflowValidator is that philosophy made into a node you can drop in your own graph. It's opt-in by placement: the moment you put it in a workflow, it reads the workflow JSON from disk and runs the same validate_workflow_contract check the pack's CI runs on every change. On success you get a one-line validation_report. On failure it raises, and ComfyUI paints the node red with the typed error - the same channel every other failure in this pack uses. No silent degradation, no "well, it kind of ran."
The mechanism is honest plumbing, and it's worth understanding because it explains what this node can and can't catch. It walks the workflow's nodes, checks each node type against NODE_CLASS_MAPPINGS, and - the part most validators skip - checks that each node's saved widgets_values length matches what its INPUT_TYPES actually declare. That last check is the one that catches the classic failure mode in this pack specifically: a node whose widget vector shifted because a saved workflow predates an added parameter. It reads the live workflow JSON from disk (the one ComfyUI is executing), not a copy.
The three required inputs are straightforward:
workflow_json_path- absolute path to the workflow JSON. Empty falls back to the pack's canonicalotr_canonical.json. If you're validating a workflow of your own, point it at that file.validate_anyway- defaulttrue. Set itfalsewhen you're deliberately loading a broken workflow to inspect intermediate state (a diagnostic use the author explicitly anticipates).strict_unknown_types- defaulttrue. When on, anOTR_-prefixed node type missing from the registry raisesWorkflowUnknownNodeTypeError. Turn it off to match the CI test default.
The optional trio - profile_id, master_hash, generated_by - is metadata for tracking which profile/hash generated the file; you can ignore them.
So when is this actually worth adding? If you're running the shipped otr_canonical.json unmodified, it's belt-and-suspenders - the workflow is already in a state the author tests. The real payoff is after you've hand-edited a workflow, upgraded the pack, or merged someone else's graph into yours. That's exactly when a saved widget vector goes stale and a node that used to work starts passing the wrong values down the line. This node catches that at queue time instead of twenty minutes into a render. The tradeoff is real but small: it's one more file path to keep honest, and it validates the file at execution time, so it can't catch problems in a workflow you haven't saved yet.
A couple of grounded cautions. The default path is baked to the pack's canonical workflow - if you validate a different file and forget to change the path, it validates the wrong graph (quietly, since an OK report on the canonical file looks great). And it only knows about contracts this pack defined; it's not a general workflow linter. Install is the pack-standard: ComfyUI Manager → "ComfyUI-OldTimeRadio", or clone https://github.com/jbrick2070/ComfyUI-OldTimeRadio into custom_nodes/, check out v2.0-alpha, restart. If you're on the wrong branch the node simply won't be there. For everyone running this pack in a loop - an OBS stream, a batch job - spending one node slot on a pre-flight check that costs milliseconds is an easy yes.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| workflow_json_path | STRING | /tmp/ComfyUI/custom_nodes/ComfyUI-OldTimeRadio/workflows/otr_canonical.json | Path of the workflow JSON this validator audits (default: the canonical graph). Template/expert field -- generated variants stamp it; a missing file fails the validation report, not the render. |
| validate_anyway | BOOLEAN | true | True: run the structural audit and RAISE on a contract or widget-vector violation, halting the queue before any model loads. False: skip the audit body and report 'skipped' -- the diagnostic bypass for a deliberately drifted graph. This flag governs the STRUCTURAL AUDIT only. Creator-input admission (My Story) always runs, in both settings, because it is what stops a blank or misdirected submission from costing an asset download. |
| strict_unknown_types | BOOLEAN | true | True: an unregistered node type in the audited JSON is a reported violation. False: unknown types are listed as informational only. Keep True on the canonical graph. |
| profile_idopt | STRING | Generation stamp: which hardware profile generated this variant. Written by build_variants, empty on the canonical master. Do not hand-edit. | |
| master_hashopt | STRING | Generation stamp: sha256 of the canonical master this variant was generated from. A mismatch against the real master means the variant is stale -- regenerate, never hand-fix. | |
| generated_byopt | STRING | Generation stamp: the tool/version that emitted this variant. Empty on the canonical master; informational in the validation report. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| validation_report | STRING | — |