Lambda Validator Guide
March 2, 2026 ยท View on GitHub
Overview
The Lambda validator provides comprehensive schema-based validation for data documents in Lambda scripts. It supports multiple input formats (XML, HTML, JSON), flexible validation options, and detailed error reporting.
Schema Definition
Basic Types
Lambda schemas use a concise, expressive syntax:
// primitive types
type Name = string
type Age = int
type Score = float
type Active = bool
// optional types (can be null)
type OptionalEmail = string?
type OptionalAge = int?
// arrays
type Names = string[]
type Numbers = int[]
type OptionalList = string[]? // array itself is optional
// maps
type Person = {
name: string,
age: int,
email: string?
}
Array Occurrence Operators
Control array cardinality with occurrence operators:
type Document = {
// zero or more elements (can be empty)
tags: string[],
// zero or more elements (can be empty) โ bracket form
comments: [string*],
// one or more elements (must have at least one)
authors: [string+],
// optional array (can be missing entirely)
attachments: string[]?
}
Nested Structures
Define complex nested types:
type Address = {
street: string,
city: string,
zipcode: string
}
type Company = {
name: string,
address: Address
}
type Person = {
name: string,
age: int,
company: Company? // optional nested structure
}
// recursive types for tree structures
type Node = {
value: int,
children: [Node*] // zero or more child nodes
}
Document Schemas
For XML/HTML validation, use element schemas:
// XML article schema
type Article = <article
title: string,
author: string,
date: string?,
tags: [string*];
<content>
<metadata id: string, status: string;>?
>
// HTML page schema
type Page = <html;
<head;
<title>
<meta name: string, content: string;>*
>
<body;
<h1>+
<p>*
<div class: string?;>*
>
>
Usage in Lambda Scripts
Basic Validation
// load schema
let schema = load_schema("schema.lmd", "Person")
// validate data
let person_data = {name: "Alice", age: 30}
let result = validate(schema, person_data)
if (result.valid) {
print("Validation passed")
} else {
print("Validation failed:")
for (error in result.errors) {
print(" - " + error.message + " at " + error.path)
}
}
Format-Aware Validation
The validator automatically detects input formats and unwraps document wrappers:
// XML validation with auto-detection
let xml_data = input("article.xml", 'xml')
let result = validate_with_format(schema, xml_data, 'xml')
// HTML validation
let html_data = input("page.html", 'html')
let result = validate_with_format(schema, html_data, 'html')
// JSON validation
let json_data = input("data.json", 'json')
let result = validate_with_format(schema, json_data, 'json')
// auto-detect format (validator inspects structure)
let data = input("document", 'auto')
let result = validate_with_format(schema, data, null)
Validation Options
Configure validation behavior with options:
// strict mode: all optional fields must be explicitly null or present
let strict_result = validate_strict(schema, data)
// limit maximum errors reported
let result = validate_with_options(schema, data, {
max_errors: 5,
strict_mode: true
})
// limit validation depth for nested structures
let result = validate_with_options(schema, data, {
max_depth: 10
})
// allow unknown fields (not in schema)
let result = validate_with_options(schema, data, {
allow_unknown_fields: true
})
Error Handling
Error Structure
Validation errors provide detailed information:
type ValidationError = {
path: string, // JSON path to error location (e.g., "person.address.city")
message: string, // human-readable error description
expected: string, // expected type or value
actual: string // actual type or value found
}
type ValidationResult = {
valid: bool,
errors: [ValidationError*]
}
Common Error Patterns
// handle type mismatches
let result = validate(schema, data)
if (!result.valid) {
for (error in result.errors) {
if (contains(error.message, "type mismatch")) {
print("Type error at " + error.path + ": expected " +
error.expected + ", got " + error.actual)
}
}
}
// handle missing required fields
let result = validate(schema, data)
if (!result.valid) {
let missing = filter(result.errors, fn(e) contains(e.message, "required"))
if (length(missing) > 0) {
print("Missing required fields:")
for (error in missing) {
print(" - " + error.path)
}
}
}
// handle array occurrence violations
let result = validate(schema, data)
if (!result.valid) {
for (error in result.errors) {
if (contains(error.message, "one or more")) {
print("Array at " + error.path + " must have at least one element")
}
}
}
Format-Specific Features
XML Document Unwrapping
The validator automatically unwraps XML <document> wrappers:
// input XML with document wrapper
// <document>
// <article>
// <title>Hello</title>
// </article>
// </document>
let xml = input("article.xml", 'xml')
let result = validate_with_format(schema, xml, 'xml')
// validator automatically unwraps <document> and validates <article>
HTML Body Extraction
HTML validation extracts the <body> element:
// input HTML
// <html>
// <head><title>Page</title></head>
// <body>
// <h1>Header</h1>
// <p>Content</p>
// </body>
// </html>
let html = input("page.html", 'html')
let result = validate_with_format(schema, html, 'html')
// validator extracts <body> and validates its contents
JSON Structure Validation
JSON validation works on maps and arrays:
// validate JSON object
let json_obj = {name: "Alice", age: 30}
let result = validate(schema, json_obj)
// validate JSON array
let json_arr = [1, 2, 3, 4, 5]
let result = validate(array_schema, json_arr)
Best Practices
1. Schema Organization
Organize schemas into reusable types:
// common types
type EmailAddress = string // can add validation later
type PhoneNumber = string
type Timestamp = string
// domain types
type User = {
id: int,
email: EmailAddress,
phone: PhoneNumber?,
created: Timestamp
}
type Post = {
id: int,
author: User,
title: string,
content: string,
published: Timestamp?
}
2. Optional vs Null
Use optional types for fields that may be omitted:
// good: optional email field
type Person = {
name: string,
age: int,
email: string? // can be missing or null
}
// validate with null (explicit null value)
let person1 = {name: "Alice", age: 30, email: null}
validate(schema, person1) // valid
// validate with missing field
let person2 = {name: "Bob", age: 25}
validate(schema, person2) // valid
// use strict mode to require explicit null
let result = validate_with_options(schema, person2, {strict_mode: true})
// invalid - email field must be present (even if null)
3. Array Constraints
Choose appropriate array occurrence operators:
// use * for optional lists (can be empty)
type Article = {
tags: [string*] // zero or more tags
}
// use + for required lists (must have elements)
type Team = {
members: [string+] // at least one member required
}
// use ? for optional arrays (can be missing entirely)
type Document = {
attachments: string[]? // array can be missing
}
4. Error Handling Strategy
Always handle validation errors gracefully:
fn validate_and_process(data) {
let result = validate(schema, data)
if (!result.valid) {
// log errors
log("Validation failed:", result.errors)
// early return or default handling
return {success: false, errors: result.errors}
}
// process valid data
return {success: true, data: process(data)}
}
5. Format Detection
Let the validator auto-detect format when possible:
// good: let validator detect format
let data = input("document", 'auto')
let result = validate_with_format(schema, data, null)
// also good: explicit format when known
let xml_data = input("article.xml", 'xml')
let result = validate_with_format(schema, xml_data, 'xml')
6. Performance Considerations
For large or deeply nested documents:
// limit validation depth
let result = validate_with_options(schema, data, {
max_depth: 20 // prevent excessive recursion
})
// limit error reporting (stop after N errors)
let result = validate_with_options(schema, data, {
max_errors: 10 // faster for documents with many errors
})
Advanced Patterns
Union Types (Future)
Note: Union types are planned for future releases
// future syntax for union types
type StringOrNumber = string | int
type Result = {success: true, data: any} | {success: false, error: string}
Type Constraints (Future)
Note: Constraint validation is planned for future releases
// future syntax for constraints
type Age = int where (value >= 0 and value <= 150)
type Email = string where matches(value, /^[^\s@]+@[^\s@]+\.[^\s@]+$/)
Schema Composition
Compose schemas from reusable parts:
// base types
type Identifiable = {
id: int,
created: string
}
type Timestamped = {
created: string,
modified: string?
}
// composed types (manually merged for now)
type User = {
id: int,
created: string,
modified: string?,
name: string,
email: string
}
API Reference
Core Functions
// load schema from file
load_schema(path: string, type_name: string) -> Schema
// validate with basic schema
validate(schema: Schema, data: Item) -> ValidationResult
// validate with format awareness
validate_with_format(schema: Schema, data: Item, format: string?) -> ValidationResult
// validate with options
validate_with_options(schema: Schema, data: Item, options: {
strict_mode: bool?,
max_errors: int?,
max_depth: int?,
allow_unknown_fields: bool?
}) -> ValidationResult
// validate with strict mode (shorthand)
validate_strict(schema: Schema, data: Item) -> ValidationResult
Format Constants
'xml' // XML format with document unwrapping
'html' // HTML format with body extraction
'json' // JSON format (maps and arrays)
null // auto-detect format
Default Options
{
strict_mode: false, // allow missing optional fields
max_errors: 100, // report up to 100 errors
max_depth: 100, // validate up to 100 levels deep
allow_unknown_fields: false // reject unknown fields
}
Examples
See examples/validation/ for complete working examples:
examples/validation/basic.lmd- Basic validationexamples/validation/xml_article.lmd- XML document validationexamples/validation/nested_types.lmd- Complex nested structuresexamples/validation/error_handling.lmd- Error handling patternsexamples/validation/options.lmd- Validation options
Troubleshooting
Common Issues
Issue: "Unknown type" error
Solution: Ensure type is defined before use. Use load_schema() to load type definitions.
Issue: Validation passes but data seems invalid
Solution: Check if allow_unknown_fields: true is set. Disable for strict validation.
Issue: "Maximum depth exceeded" error
Solution: Increase max_depth option or check for circular references in data.
Issue: XML validation fails on wrapped documents
Solution: Use validate_with_format() with 'xml' format to auto-unwrap.
Issue: Too many validation errors
Solution: Set max_errors to stop early and inspect first few errors.
Further Reading
- Lambda Reference Manual - Complete language reference
- Lambda Cheatsheet - Quick syntax reference
- Type System Documentation - Detailed type system guide