Skip to content

Validation System

Moira performs comprehensive validation at multiple levels to ensure workflow integrity and correct agent responses.

Workflows are validated against a JSON Schema definition:

  • Structure validation against workflow schema
  • Required field checking (id, metadata, nodes)
  • Type validation for all properties
  • Enum validation for node types

Graph structure is analyzed for correctness:

  • Node connectivity - All connections point to valid nodes
  • Required nodes - Start node must exist
  • Circular dependencies - Loops are detected and flagged
  • Unreachable nodes - Nodes not connected from start

Agent responses are validated against inputSchema:

  • AJV-based JSON Schema validation
  • Type checking for response fields
  • Required field validation
  • Pattern and format validation

Validation returns structured results:

{
valid: boolean;
errors: ValidationError[];
warnings: ValidationWarning[];
}
TypeDescriptionExample
schemaJSON structure invalidMissing required field
structureGraph structure invalidOrphan node
connectionConnection invalidPoints to non-existent node
referenceReference invalidInvalid subgraph ID
TypeDescriptionThreshold
performanceLarge workflow>20 agent-directive nodes
complexityComplex conditionsDeeply nested conditions
contextLarge context>100KB context size
{
"id": "valid-workflow",
"metadata": {
"name": "Valid Workflow",
"version": "1.0.0",
"description": "A valid workflow"
},
"nodes": [
{ "id": "start", "type": "start", "connections": { "default": "task" } },
{
"id": "task",
"type": "agent-directive",
"directive": "...",
"completionCondition": "...",
"connections": { "success": "end" }
},
{ "id": "end", "type": "end" }
]
}

Result:

{ "valid": true, "errors": [], "warnings": [] }
{
"nodes": [
{ "id": "start", "type": "start", "connections": { "default": "missing" } },
{ "id": "end", "type": "end" }
]
}

Result:

{
"valid": false,
"errors": [
{
"type": "connection",
"message": "Node 'start' references non-existent node 'missing'",
"nodeId": "start"
}
]
}

Large workflow triggers performance warning:

{
"valid": true,
"errors": [],
"warnings": [
{
"type": "performance",
"message": "Workflow has 25 agent-directive nodes. Consider breaking into subgraphs.",
"count": 25
}
]
}

Agent responses are validated against inputSchema defined on agent-directive nodes.

Nodes without inputSchema require empty input from agent. Non-empty responses are rejected:

// Node without inputSchema
{ "id": "task", "type": "agent-directive", "directive": "..." }
// Valid: empty response
{}
// Invalid: non-empty response
{ "result": "done" } // Rejected with validation error
{
"type": "agent-directive",
"inputSchema": {
"type": "object",
"properties": {
"result": { "type": "string" },
"confidence": { "type": "number", "minimum": 0, "maximum": 10 }
},
"required": ["result"]
}
}
{ "result": "completed", "confidence": 8 }
{ "confidence": "high" }

Error:

{
"valid": false,
"errors": [
{ "field": "result", "message": "Required field missing" },
{ "field": "confidence", "message": "Expected number, got string" }
]
}
  1. Always include inputSchema - Validate agent responses for consistent data
  2. Keep workflows focused - Split large workflows into subgraphs
  3. Test validation - Use manage_workflow with includeValidation: true
  4. Handle errors gracefully - Define error connections for validation failures