SOP Validation Guide¶
Overview¶
Validation ensures your SOP conforms to the SOPTemplateSchema and will render correctly in CLAIRE. This guide covers validation methods, common errors, and troubleshooting strategies.
Why Validation Matters¶
Prevents Runtime Errors: Catches issues before deployment
Ensures Data Integrity: Validates field types and constraints
Maintains Consistency: Enforces standard structure across all SOPs
Improves User Experience: Prevents broken forms in CLAIRE
Validation Process¶
SAM uses Zod schema validation with strict mode enabled, meaning:
All required fields must be present
Field types must match declarations exactly
No additional properties are allowed (
additionalProperties: false)References must point to valid definitions
Validation Methods¶
Method 1: SAM Editor (Recommended)¶
The easiest way to validate is directly in the SAM editor:
Open your SOP in SAM
Click the Validate button in the toolbar
Review results in the validation panel
Fix any errors shown
Re-validate until all checks pass
Visual Indicators:
✅ Green checkmark = Valid
❌ Red X = Invalid
⚠️ Yellow warning = Non-critical issues
Method 2: Command Line¶
For batch validation or CI/CD pipelines:
# Validate a single SOP
make validate-sop FILE=path/to/your-sop.yaml
# Validate all SOPs in a directory
make validate-all-sops DIR=.local/s3/forms/sops
# Validate with verbose output
make validate-sop FILE=sop.yaml VERBOSE=true
Method 3: Programmatic Validation¶
For custom scripts or automation:
import { validateSOP } from '@shared/lib/sop-validator';
const result = await validateSOP(sopYamlContent);
if (result.valid) {
console.log('✅ SOP is valid');
} else {
console.error('❌ Validation errors:', result.errors);
}
Understanding Validation Errors¶
Error Structure¶
Validation errors follow this format:
Field: [path.to.field]
Error: [error description]
Expected: [what was expected]
Received: [what was provided]
Common Validation Errors¶
1. Missing Required Field¶
Error:
Field: [root].author
Error: Required field missing
Expected: string
Received: undefined
Solution: Add the missing field with appropriate value:
author: "Dr. Jane Smith"
2. Type Mismatch¶
Error:
Field: [taskgroups.0.ordinal]
Error: Invalid type
Expected: number
Received: string "1"
Solution: Use correct type (no quotes for numbers):
ordinal: 1 # Not "1"
3. Additional Properties¶
Error:
Field: [taskgroups.0]
Error: Unrecognized key(s) in object: 'customField'
Solution: Remove unknown properties or move to appropriate location:
# Remove customField or place in children array
4. Invalid Enum Value¶
Error:
Field: [root].status
Error: Invalid enum value
Expected: one of ["draft", "published", "deprecated"]
Received: "pending"
Solution: Use allowed value:
status: "draft" # or "published" or "deprecated"
5. Invalid Date Format¶
Error:
Field: [root].date-published
Error: Invalid date format
Expected: YYYY-MM-DD
Received: "01/15/2024"
Solution: Use ISO date format:
date-published: "2024-01-15"
6. Pattern Mismatch¶
Error:
Field: [fields.project_id].value
Error: String does not match pattern
Pattern: ^PROJ-[0-9]{4}$
Received: "PROJECT-001"
Solution: Match required pattern:
value: "PROJ-0001"
Validation Rules¶
Metadata Validation¶
Field |
Rules |
|---|---|
|
Required, unique string |
|
Required string, max 100 chars |
|
Required, semantic version format |
|
Required string |
|
Required, ISO date format |
|
Required enum: draft/published/deprecated |
|
Required, valid URI format |
|
Required string |
Structure Validation¶
Task Groups¶
Must have unique
idMust contain
childrenarrayChildren must be valid Task objects
ordinalmust be positive integer if present
Tasks¶
Must have unique
idMust have
@type: TaskMust be child of TaskGroup
Can contain Field children
Fields¶
Must have unique
idMust have
typeproperty to renderrequiredmust be booleanValidation rules must match type
Type-Specific Validation¶
String Fields¶
validation:
minLength: 1
maxLength: 255
pattern: "regex"
enum: ["option1", "option2"]
Number Fields¶
validation:
min: 0
max: 100
multipleOf: 0.5
integer: true # No decimals
Array Fields¶
validation:
minItems: 1
maxItems: 10
uniqueItems: true
File Fields¶
file_config:
accept: ".pdf,.jpg" # File types
maxSize: 10485760 # Bytes (10MB)
multiple: false # Single file only
Advanced Validation¶
Cross-Field Validation¶
Validate relationships between fields:
cross_field_validations:
- name: "date_range_check"
fields: ["start_date", "end_date"]
condition:
type: "comparison"
operator: "less_than_or_equal"
error_message: "Start date must be before end date"
Conditional Validation¶
Apply rules based on other fields:
conditional_validation:
- when:
field: "sample_type"
equals: "blood"
then:
field: "volume_ml"
required: true
min: 0.1
max: 50
Custom Validation Messages¶
Provide user-friendly error messages:
validation:
pattern: "^[A-Z]{3}-[0-9]{4}$"
message: "Format must be: XXX-0000 (3 letters, hyphen, 4 digits)"
Validation Best Practices¶
Before Validation¶
Review YAML syntax: Use a YAML linter first
Check structure: Ensure proper indentation
Verify IDs: All IDs must be unique
Complete metadata: Fill all required fields
During Validation¶
Validate frequently: Check after each major change
Read errors carefully: Error messages contain solutions
Fix top errors first: They may cascade
Use debug panel: Visual feedback helps
After Validation¶
Test in preview: Ensure form renders correctly
Try sample data: Enter test values
Check all tabs: Navigate through entire form
Export and review: Verify YAML output
Troubleshooting Validation¶
Validation Won’t Run¶
Possible Causes:
YAML syntax errors
Missing file
Network issues (if validating remotely)
Solutions:
Check YAML with external validator
Verify file path
Check network connectivity
False Positives¶
Symptom: Valid SOP shows errors
Check:
Schema version compatibility
Cache may need clearing
Browser console for JavaScript errors
Fix:
# Clear cache and rebuild
make clean-cache
make build-schemas
Validation Passes but Form Broken¶
Likely Issues:
UI configuration conflicts
Circular references
Missing parent-child relationships
Debug Steps:
Check browser console
Review parent-child links
Verify no circular dependencies
Test with minimal SOP
Validation Workflow¶
graph TD
A[Create/Edit SOP] --> B[Run Validation]
B --> C{Valid?}
C -->|No| D[Review Errors]
D --> E[Fix Issues]
E --> B
C -->|Yes| F[Test in Preview]
F --> G{Works?}
G -->|No| H[Debug Issues]
H --> A
G -->|Yes| I[Ready for Deployment]
Command Reference¶
CLI Commands¶
# Basic validation
sam validate <file>
# Verbose mode
sam validate <file> --verbose
# Output format
sam validate <file> --format json
# Strict mode (default)
sam validate <file> --strict
# Validate against specific schema version
sam validate <file> --schema-version 2.0
Make Targets¶
# Validate single SOP
make validate-sop FILE=<path>
# Validate directory
make validate-sops-dir DIR=<path>
# Validate and fix (auto-fix simple issues)
make validate-fix FILE=<path>
# Validation report
make validation-report DIR=<path>
Validation Tools¶
Online Validators¶
YAML Validator - Check YAML syntax
JSON Schema Validator - Test schema compliance
RegEx101 - Test pattern validation
VS Code Extensions¶
YAML by Red Hat - YAML syntax validation
Better YAML - Advanced YAML support
Zod Schema - Zod schema validation
Browser DevTools¶
Use browser console to debug:
// Check validation state
console.log(window.__SAM_VALIDATION_STATE__);
// Manually trigger validation
window.__SAM_VALIDATE_CURRENT__();
// Export validation report
window.__SAM_EXPORT_VALIDATION_REPORT__();
Performance Considerations¶
Large SOPs¶
For SOPs with many fields (>100):
Incremental validation: Validate sections separately
Lazy validation: Only validate changed fields
Async validation: Use background validation
Cache results: Store validation state
Complex Validation Rules¶
For complex cross-field validation:
Simplify when possible: Break into smaller rules
Use meaningful names: Make debugging easier
Document dependencies: Note field relationships
Test thoroughly: Edge cases matter
Integration with CI/CD¶
GitHub Actions Example¶
name: Validate SOPs
on:
push:
paths:
- 'sops/*.yaml'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v2
- name: Install dependencies
run: npm install
- name: Validate SOPs
run: make validate-all-sops
Pre-commit Hook¶
#!/bin/bash
# .git/hooks/pre-commit
# Validate changed SOPs
for file in $(git diff --cached --name-only | grep "\.yaml$"); do
make validate-sop FILE=$file || exit 1
done
Summary¶
Key validation points:
✅ Always validate before deployment ✅ Fix all errors, not just critical ones ✅ Test thoroughly after validation ✅ Use appropriate validation method for context ✅ Keep SOPs simple and well-structured