
workflow-validation
by seer-engg
no-code, controllable AI workflows
SKILL.md
name: workflow-validation description: Validates workflow schemas, expressions, and block configurations in seer. Use when reviewing workflow changes, adding new blocks, debugging workflow compilation errors, or validating workflow JSON structures. allowed-tools: Read, Grep, Glob, Bash(pytest:*)
Workflow Validation Skill
Validates workflow specifications through a 5-stage compilation pipeline. Use when working on workflow-related code. See workflow_compiler/README.md for architecture overview.
Compilation Pipeline
Validation happens across 5 stages:
- Parse (
compiler/parse.py): JSON → PydanticWorkflowSpec(structural validation) - Type Environment (
compiler/type_env.py): Build type environment from schemas → RaisesTypeEnvironmentError - Validate References (
compiler/validate_refs.py): Check${...}references exist → RaisesValidationPhaseError - Lower (
compiler/lower_control_flow.py): Transform to execution plan → RaisesLoweringError - Emit (
compiler/emit_langgraph.py): Generate LangGraph StateGraph
Runtime: Expression evaluation and output validation
Error Hierarchy
WorkflowCompilerError (base)
├── ValidationPhaseError (Stage 1-3: structural/reference validation)
├── TypeEnvironmentError (Stage 2: type env construction)
├── LoweringError (Stage 4: lowering failures)
└── ExecutionError (runtime: tool execution, schema validation)
└── EvaluationError (runtime: expression evaluation)
Key Validation Components
1. Input Validation (workflow_compiler/runtime/input_validation.py)
Validates and coerces runtime inputs against the workflow spec.
Key patterns:
- Uses
InputDeffromworkflow_compiler/schema/models.pyfor type definitions - Supports types:
string,integer,number,boolean,object,array - Applies default values declared on each InputDef
- Raises
WorkflowCompilerErrorif required input is missing or cannot be coerced
Type coercion rules:
string: Accepts str, int, float, bool (converts to string)integer: Accepts int, or parses from stringnumber: Accepts int/float, or parses from stringboolean: Accepts bool, or parses from string literals (true,false,1,0,yes,no,on,off)object: Accepts dict, or parses JSON from stringarray: Accepts list, tuple, or parses JSON from string
Example validation:
from seer.core.runtime.input_validation import coerce_inputs
from seer.core.schema.models import WorkflowSpec
# Validate inputs against spec
coerced = coerce_inputs(spec, provided_inputs)
2. Reference Validation (workflow_compiler/compiler/validate_refs.py)
Validates all ${...} references against the computed type environment.
Key patterns:
- Uses
TypeEnvironmentandScopefromworkflow_compiler/expr.typecheck - Validates references in node inputs, values, prompts, and conditions
- Handles nested scopes for
for_eachloops (withitem_varandindex_varlocals) - Raises
ValidationPhaseErrorwith detailed error messages
Reference resolution order:
- Local variables (loop variables, etc.)
- State variables (node outputs)
- Special
inputsobject (workflow inputs) - Config variables (if provided)
Example validation:
from seer.core.compiler.validate_refs import validate_references
from seer.core.expr.typecheck import TypeEnvironment
# Validate all references in workflow
type_env = TypeEnvironment()
validate_references(spec, type_env)
3. Expression Evaluation (workflow_compiler/expr/evaluator.py)
Runtime evaluation of ${...} expressions.
Key patterns:
- Uses
EvaluationContextwith state, inputs, locals, and config - Supports property access (
${node.field}) and index access (${array[0]}) - Raises
EvaluationErrorfor unknown references or invalid access
Context structure:
from seer.core.expr.evaluator import EvaluationContext, resolve_reference
ctx = EvaluationContext(
state={"node1": {"output": "value"}},
inputs={"user_input": "test"},
locals={"item": "current_item", "index": 0},
config={"api_key": "***"}
)
4. Schema Models (workflow_compiler/schema/models.py)
Pydantic models for workflow specification.
Key patterns:
- All models extend
StrictModel(extra="forbid", validate_assignment=True) - Uses
@model_validatorfor cross-field validation - Supports
SchemaRef(reference to known schema) andInlineSchema(JSON Schema)
Important types:
WorkflowSpec: Top-level workflow definitionNode: Base class for all block types (if_else, for_each, llm, tool, etc.)InputDef: Input parameter definition with type and default valueOutputContract: Declares what a node writes (text or JSON with schema)
5. JSON Schema Validation (workflow_compiler/schema/jsonschema_adapter.py)
Core JSON Schema validation utilities using jsonschema library (Draft 2020-12).
Key functions:
get_validator(schema): Returns Draft202012Validatorvalidate_instance(instance, schema): Validates data against schemacheck_schema(schema): Validates schema structuredereference_schema(schema): Resolves$refreferencesformat_validation_error(error): Human-friendly error messages
Example:
from seer.core.schema.jsonschema_adapter import validate_instance
validate_instance({"name": "test"}, {"type": "object", "properties": {"name": {"type": "string"}}})
6. Runtime Output Validation (workflow_compiler/runtime/validate_output.py)
Runtime JSON schema validation wrapper.
Key patterns:
- Uses
validate_against_schema(value, schema)to check node outputs - Raises
ExecutionErrorfor schema mismatches - Called after tool/LLM nodes execute when
OutputContractspecifies JSON mode
7. Parsing (workflow_compiler/compiler/parse.py)
Stage 1 compilation: Parse JSON dict → WorkflowSpec.
Key function:
parse_workflow_spec(spec_dict): Validates structure with Pydantic- Raises
ValidationPhaseErrorfor missing required fields, invalid node types
Common Validation Scenarios
When Adding a New Block Type
-
Define the block model in
workflow_compiler/schema/models.py- Extend
Nodebase class - Use Pydantic field validators for constraints
- Add to the
Nodeunion type
- Extend
-
Add validation logic if the block has special requirements
- Reference validation in
validate_refs.py - Input coercion in
input_validation.py - Runtime evaluation in
evaluator.py
- Reference validation in
-
Write tests in
workflow_compiler/tests/- Test valid configurations
- Test invalid inputs (should raise appropriate errors)
- Test edge cases (empty values, null handling, etc.)
When Reviewing Workflow Changes
Check for:
- Required fields: All required fields are present (use Pydantic validation)
- Type safety: References resolve to correct types
- Expression syntax:
${...}expressions are valid and references exist - Schema compliance: JSON output matches declared schemas
- Error handling: Validation errors provide clear, actionable messages
When Debugging Compilation Errors
Common error types:
-
ValidationPhaseError: Structural/reference validation failed (Stages 1-3)
- Check
compiler/parse.py:parse_workflow_spec()for parsing errors - Check
compiler/validate_refs.py:validate_references()for${...}reference errors - Verify required fields, node types, and references exist
- Check
-
TypeEnvironmentError: Type environment construction failed (Stage 2)
- Check
compiler/type_env.py - Verify node output schemas are valid and schema refs resolve
- Check
-
LoweringError: Lowering to execution plan failed (Stage 4)
- Check
compiler/lower_control_flow.py - Verify control flow structures (if_else, for_each) are valid
- Check
-
ExecutionError: Runtime execution failed
- Check
runtime/validate_output.pyfor schema validation errors - Check tool execution errors in
runtime/nodes.py
- Check
-
EvaluationError: Expression evaluation failed (runtime)
- Check
expr/evaluator.py:resolve_reference() - Verify state contains expected values for
${...}expressions
- Check
Testing Workflow Validation
Run validation tests:
# Run all workflow compiler tests
pytest workflow_compiler/tests/
# Run specific validation tests
pytest workflow_compiler/tests/test_input_validation.py
pytest workflow_compiler/tests/test_jsonschema_adapter.py
# Run with verbose output
pytest -v workflow_compiler/tests/
Best Practices
- Fail fast with clear errors: Validation should catch errors early with actionable messages
- Type coercion is lenient: Allow reasonable conversions (string to number, etc.)
- Validation is layered: 5-stage compilation pipeline catches errors progressively
- Preserve extra inputs: Don't discard inputs not declared in spec (forwards compatibility)
- Use nested scopes: Loop variables (
item_var,index_var) are local to loop body
Key Files Reference
| File | Purpose | Stage/Phase |
|---|---|---|
compiler/parse.py | Parse JSON → WorkflowSpec | Stage 1 |
compiler/type_env.py | Build type environment | Stage 2 |
compiler/validate_refs.py | Validate ${...} references | Stage 3 |
compiler/lower_control_flow.py | Lower to execution plan | Stage 4 |
compiler/emit_langgraph.py | Emit LangGraph StateGraph | Stage 5 |
schema/models.py | Pydantic models for workflow spec | All stages |
schema/jsonschema_adapter.py | JSON Schema validation utilities | Stages 2-3, Runtime |
runtime/input_validation.py | Input coercion and validation | Runtime |
runtime/validate_output.py | Runtime output schema validation | Runtime |
expr/evaluator.py | Runtime expression evaluation | Runtime |
expr/typecheck.py | Type checking for references | Stage 2-3 |
errors.py | Error hierarchy | All |
README.md | Architecture overview | Reference |
Quick Checklist
When validating workflow changes:
- All required fields are present
- Input types match InputDef declarations
- All
${...}references resolve to existing state/inputs - Output contracts specify schemas when mode=json
- Nested blocks (if_else, for_each) have valid children
- Loop variables are scoped correctly
- Tests cover success and error cases
- Error messages are clear and actionable
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
1ヶ月以内に更新
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon

