How Modly Validates Workflow Wiring and Detects Invalid Node Connections

Modly validates workflow wiring through a static "pre-flight" analysis that inspects node connections, resolves data types through passthrough chains, and detects specific wiring errors like missing inputs or illegal Wait branch merges before execution begins.

Modly, an open-source workflow engine maintained by lightningpixel/modly, ensures reliable pipeline execution by validating node connections prior to runtime. The system performs a comprehensive static analysis to catch wiring errors—such as type mismatches, disconnected inputs, or invalid branch merges—preventing runtime failures in complex creative workflows.

The Pre-Flight Validation Architecture

The validation logic centers on validateWorkflowPreflight in src/areas/workflows/preflight.ts. This function orchestrates type resolution and error detection by collaborating with utility functions in src/areas/workflows/nodeBehaviors.ts. Together, these modules create a pre-flight validation system that analyzes the workflow graph without executing it.

Collecting and Resolving Data Types

Before detecting connection errors, Modly must determine what data type each node produces.

Determining Node Output Types

The getNodeOutputType function in preflight.ts inspects each node's intrinsic type to establish its output data type. For built-in nodes, this returns standard types like image, text, mesh, or audio. For extension nodes, the function reads the extension's declared output type from its manifest. These mappings are stored in a Map<string, DataType> called outputTypes for O(1) lookup during subsequent validation steps.

Resolving Passthrough Data Sources

Passthrough nodes—such as wait nodes—forward data without transformation, complicating type tracking. The resolveDataSource helper (in nodeBehaviors.ts) traverses backwards through consecutive passthrough nodes until it locates the actual source node. Once identified, the source's output type propagates to the passthrough node, ensuring type consistency throughout the chain.

Detecting Specific Wiring Problems

With type information resolved, validateWorkflowPreflight iterates through every node to identify specific connection errors.

Missing Scene Resources and Empty Folders

The validator checks for configuration errors in specialized nodes. A meshNode configured to "Current Scene" must provide a valid mesh URL; otherwise, the system generates a missing current mesh error. Similarly, For-Each nodes must specify a folder path—the validator flags empty folder selections as wiring issues before execution.

Illegal Wait Branch Merging

Using the nearestUpstreamWaits helper in nodeBehaviors.ts, Modly detects when a node consumes inputs from multiple upstream Wait branches. This pattern is illegal because the node would trigger before any branch produces a mesh, resulting in undefined behavior. The validator flags such connections immediately, preventing race conditions in asynchronous workflows.

Extension Node Connection Validation

Extension nodes undergo rigorous input validation to ensure compatibility with the underlying extension:

  • Extension existence – The validator confirms the extensionId references a loaded extension from the installed extensions list.
  • Required input coverage – For each required input type declared by the extension, the system verifies at least one incoming edge provides a matching output type from the outputTypes map.
  • Type mismatch detection – If an incoming edge supplies a type not accepted by the extension (e.g., feeding audio into an extension expecting only image), the validator records a specific type mismatch error.

Issue Aggregation and Reporting

All detected problems accumulate in the issues array as WorkflowPreflightIssue objects. Each issue contains a unique key, a human-readable message, and the offending node ID. The pushIssue utility prevents duplicate entries when multiple validation checks identify the same problem. The validateWorkflowPreflight function returns this array—an empty array indicates valid workflow wiring ready for execution.

Practical Implementation Example

Here's how to invoke the validator in your own Modly implementation:

import { validateWorkflowPreflight } from '@/areas/workflows/preflight'
import { getWorkflowExtension } from '@/areas/workflows/mockExtensions'

// Example workflow (simplified)
const workflow = {
  nodes: [
    { id: '1', type: 'imageNode', data: {} },
    { id: '2', type: 'extensionNode', data: { extensionId: 'myExt' } },
    { id: '3', type: 'outputNode', data: {} },
  ],
  edges: [
    { id: 'e1', source: '1', target: '2' },
    { id: 'e2', source: '2', target: '3' },
  ],
}

// Load all installed extensions (mocked here)
const allExtensions = [getWorkflowExtension('myExt', [])].filter(Boolean)

// Run the pre‑flight validator
const issues = validateWorkflowPreflight(workflow, allExtensions)

// `issues` will be empty if wiring is correct, otherwise it contains descriptive errors.
if (issues.length) {
  console.warn('Workflow has wiring problems:', issues)
} else {
  console.log('Workflow wiring is valid!')
}

Summary

  • Modly performs static pre-flight validation in validateWorkflowPreflight before executing any workflow.
  • Type resolution relies on getNodeOutputType and resolveDataSource to handle passthrough chains correctly.
  • The system detects missing inputs, type mismatches, and illegal Wait branch merges using nearestUpstreamWaits.
  • Extension nodes undergo specialized validation for existence and input compatibility.
  • All issues aggregate as WorkflowPreflightIssue objects, enabling clear debugging feedback.

Frequently Asked Questions

What happens if Modly detects invalid node connections during validation?

If validateWorkflowPreflight returns a non-empty issues array, the workflow execution is blocked and the interface displays descriptive error messages for each WorkflowPreflightIssue. Users must resolve missing inputs, type mismatches, or illegal branch merges before the workflow can run.

How does Modly handle data types through passthrough nodes?

Modly uses the resolveDataSource helper in nodeBehaviors.ts to trace backwards through passthrough nodes (like Wait nodes) until finding the actual source. The source's output type then propagates forward, ensuring downstream nodes receive correct type information regardless of intermediate passthrough chains.

Can Modly validate custom extension nodes?

Yes. The validator specifically handles extensionNode types by checking that the referenced extension is loaded and that all required inputs are satisfied by incoming edges with compatible types. This prevents runtime errors when third-party extensions receive unexpected data formats.

Where is the workflow validation logic located in the Modly repository?

The core validation logic resides in src/areas/workflows/preflight.ts, with supporting graph traversal utilities in src/areas/workflows/nodeBehaviors.ts. Type definitions for workflows and nodes are found in src/shared/types/electron.d.ts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →