Skip to content

Pipeline Validation ​

Prerequisites: Defining Pipelines

NPipeline validates your pipeline graph when you call Build(). Validation catches structural errors - disconnected nodes, type mismatches, cycles - before execution begins.

Validation Modes ​

Control validation behavior with WithValidationMode:

csharp
// Default: throw PipelineValidationException on errors
builder.WithValidationMode(GraphValidationMode.Error);

// Log warnings but allow execution
builder.WithValidationMode(GraphValidationMode.Warn);

// Skip validation entirely (not recommended)
builder.WithValidationMode(GraphValidationMode.Off);

Built-In Rules ​

Core Rules (Always Run) ​

RuleStops BuildWhat It Checks
UniqueNodeNameRuleYesNo duplicate node names
DuplicateNodeIdRuleYesNo duplicate node IDs
EdgeReferenceRuleYesAll edges reference existing nodes
SourceAndReachabilityRuleNoAt least one source; all nodes reachable
UnconsumedOutputRuleNoEvery non-sink node's output is consumed downstream
JoinInputsRuleNoEvery join has both its left and right inputs connected
CycleDetectionRuleNoGraph is a DAG (no cycles)
ResilienceOptionsRuleNoItem retry, node restart and circuit breakers are set only on transforms; node restart uses a resumable strategy

Extended Rules (Opt-Out) ​

Extended rules add configuration and best-practice checks:

RuleWhat It Checks
MissingSinkRuleAt least one sink node exists
SelfLoopRuleNo edges from a node to itself
DuplicateEdgeRuleNo duplicate edges between same node pair
TypeCompatibilityRuleOutput type is assignable to downstream input type
ParallelConfigurationRuleParallel nodes have bounded queues and reasonable DOP

Disable extended rules if needed:

csharp
builder.WithoutExtendedValidation();

Pre-Build Validation ​

Validate without building:

csharp
PipelineValidationResult result = builder.Validate();

if (!result.IsValid)
{
    foreach (var error in result.Errors)
        Console.WriteLine($"Error: {error}");
    foreach (var warning in result.Warnings)
        Console.WriteLine($"Warning: {warning}");
}

Check if a specific connection is valid:

csharp
if (builder.CanConnect(source, target, out string? reason))
    builder.Connect(source, target);
else
    Console.WriteLine($"Cannot connect: {reason}");

Safe Build with TryBuild ​

TryBuild returns false instead of throwing on validation failures:

csharp
if (builder.TryBuild(out var pipeline, out var validationResult))
{
    await runner.RunAsync(pipeline);
}
else
{
    foreach (var issue in validationResult.Issues)
        Console.WriteLine($"[{issue.Severity}] {issue.Message}");
}

Custom Validation Rules ​

Add project-specific rules by implementing IGraphRule:

csharp
public class RequireNamingConventionRule : IGraphRule
{
    public string Name => "Naming Convention";
    public bool StopOnError => false;

    public IEnumerable<ValidationIssue> Evaluate(GraphValidationContext context)
    {
        foreach (var node in context.Graph.Nodes)
        {
            if (!node.Name.Contains('-'))
            {
                yield return new ValidationIssue(
                    ValidationSeverity.Warning,
                    $"Node '{node.Name}' should use kebab-case naming",
                    "Convention");
            }
        }
    }
}

builder.WithValidationRule(new RequireNamingConventionRule());

Pipeline Visualization ​

Inspect the pipeline graph structure:

csharp
// Generate a Mermaid diagram
string mermaid = builder.ToMermaidDiagram();
Console.WriteLine(mermaid);

// Text description of the graph
string description = builder.Describe();

💡 Tip: Roslyn analyzers (NP9xxx) provide additional compile-time checks beyond graph validation. See Analyzer Rules for the full catalog.

Next Steps ​

Released under the MIT License.