yamlvalidator

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 24, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

README

yamlvalidator

A flexible, production-ready YAML validation library for Go with support for:

  • Type checking with YAML 1.2 (and optional YAML 1.1) compliance
  • Full JSON Schema validation with draft-04, draft-06, draft-07, 2019-09, and 2020-12 support
  • Custom validators for values and keys
  • Conditional logic (AnyOf, ExactlyOneOf, MutuallyExclusive, Conditions)
  • Detailed error reporting with source context and precise positions
  • Multi-document YAML support
  • Anchor/alias support
  • Unicode and tab handling in error output

Installation

Requires Go 1.24 or newer. CI verifies the minimum supported Go 1.24 line and the current stable Go release. Security-fixed IDNA/Unicode code is kept in an internal third-party snapshot so full idn-hostname/idn-email support does not force consumers onto Go 1.25.

go get github.com/Yakwilik/go-yamlvalidator@v1.0.0

Quick Start

package main

import (
    "fmt"
    "regexp"

    v "github.com/Yakwilik/go-yamlvalidator"
    valv "github.com/Yakwilik/go-yamlvalidator/pkg/valuevalidator"
)

func main() {
    schema := &v.FieldSchema{
        Type: v.TypeMap,
        AllowedKeys: map[string]*v.FieldSchema{
            "name": {
                Type:     v.TypeString,
                Required: true,
                Validators: []v.ValueValidator{
                    valv.RegexValidator{
                        Pattern: regexp.MustCompile(`^[a-z][a-z0-9-]*$`),
                        Message: "must be lowercase with dashes",
                    },
                },
            },
            "replicas": {
                Type: v.TypeInt,
                Validators: []v.ValueValidator{
                    valv.RangeValidator{Min: v.Ptr[float64](1), Max: v.Ptr[float64](100)},
                },
            },
        },
    }

    yaml := []byte(`
name: my-app
replicas: 50
`)

    validator := v.NewValidator(schema)
    result := validator.ValidateBytes(yaml)

    if result.HasErrors() {
        fmt.Println(result.FormatAll(true))
    }
}

Schema Definition

Field Schema
type FieldSchema struct {
    // Basic properties
    Type         NodeType   // Expected type (TypeString, TypeInt, etc.)
    AllowedTypes []NodeType // Accept any listed type; takes precedence over Type
    Required     bool       // Field must be present
    Nullable    bool        // Allow null values
    Deprecated  string      // Deprecation message (empty = not deprecated)
    Description string      // Human-readable description
    Default     interface{} // Suggested default; emits warning if omitted, does not mutate input

    // Map-specific
    AllowedKeys          map[string]*FieldSchema // Known keys
    AdditionalProperties *FieldSchema            // Schema for unknown keys
    UnknownKeyPolicy     UnknownKeyPolicy        // How to handle unknown keys
    KeyValidators        []KeyValidator          // Key name validators

    // Sequence-specific
    ItemSchema *FieldSchema // Schema for items
    MinItems   *int
    MaxItems   *int

    // Value validators
    Validators []ValueValidator

    // Inter-field logic
    AnyOf             [][]string        // At least one group must be present
    ExactlyOneOf      []string          // Exactly one field must be present
    MutuallyExclusive []string          // At most one field can be present
    Conditions        []ConditionalRule // Conditional validation
    OneOfRequired     [][]string        // Exactly one field group must be present
    ForbiddenTogether [][]string        // A complete field group is forbidden
    DependentRequired map[string][]string

    // Schema composition
    OneOfSchemas []*FieldSchema // Exactly one schema must match
    AnyOfSchemas []*FieldSchema // At least one schema must match
}
Native schema compilation

For schemas assembled dynamically, prefer CompileFieldSchema over constructing a validator directly. It rejects invalid schema graphs before any YAML is validated: recursive graphs, incompatible map/sequence constraints, invalid min/max bounds, nil validators, bad regexp definitions, invalid inter-field references, and other definition errors.

validator, err := v.CompileFieldSchema(schema)
if err != nil {
    return err
}

CompileFieldSchema also snapshots the FieldSchema graph (maps, slices, nested schemas, item limits, conditions, and ordinary JSON/YAML container defaults). Later mutations of the source schema therefore do not change the compiled validator. Opaque application-defined objects stored in Default, plus custom ValueValidator / KeyValidator instances, are copied by value and remain the caller's concurrency responsibility. A compiled validator can otherwise be reused concurrently.

NewValidator remains available for backwards compatibility when the schema is already trusted; unlike CompileFieldSchema, it retains the supplied schema pointer directly.

Node Types
Type Description
TypeAny Any type; bare maps/sequences are not recursively constrained
TypeNull Null values only
TypeString String values
TypeInt Integer values
TypeFloat Float values (also accepts int)
TypeBool Boolean values
TypeMap Mapping nodes
TypeSequence Sequence/array nodes
Unknown Key Policy
Policy Behavior
UnknownKeyInherit Uses ctx.StrictKeys (default)
UnknownKeyError Unknown keys are errors
UnknownKeyWarn Unknown keys are warnings
UnknownKeyIgnore Unknown keys are ignored

JSON Schema Compilation

CompileJSONSchema compiles a standards-compliant JSON Schema and returns a FieldSchema adapter. Validation is delegated to a full JSON Schema engine; the YAML validator remains responsible for parsing YAML, preserving source positions, resolving YAML aliases/merge keys, converting the YAML value to the JSON data model, and mapping JSON Schema errors back to YAML diagnostics.

Supported dialects:

  • JSON Schema draft-04
  • JSON Schema draft-06
  • JSON Schema draft-07
  • JSON Schema 2019-09
  • JSON Schema 2020-12

An explicit $schema selects the dialect. Without $schema, draft 2020-12 is used by default and can be changed with DefaultDraft.

All keywords implemented by the engine are available, including references and modern applicators such as $ref, $dynamicRef, $defs, $anchor, allOf, anyOf, oneOf, if/then/else, dependentSchemas, unevaluatedProperties, unevaluatedItems, prefixItems, contains, numeric/string/object/array constraints, boolean schemas, annotations, and vocabulary declarations. Unknown extension keywords follow JSON Schema semantics instead of being rejected merely because yamlvalidator does not know them.

schemaJSON, err := os.ReadFile("config.schema.json")
if err != nil {
    return err
}

schema, err := v.CompileJSONSchema(schemaJSON)
if err != nil {
    return err
}

result := v.NewValidator(schema).ValidateBytes(yamlData)
Compilation options
policy := v.UnknownKeyWarn
schema, err := v.CompileJSONSchemaWithOptions(schemaJSON, v.JSONSchemaCompileOptions{
    SchemaURL:    "https://schemas.example.com/config.json",
    DefaultDraft: v.JSONSchemaDraft2020,

    AssertFormat:  true,
    AssertContent: true,
    AssertVocabs:  true,
    RegexpTimeout: 500 * time.Millisecond, // Optional protection for untrusted schemas

    Resources: map[string][]byte{
        "https://schemas.example.com/common.json": commonSchema,
    },

    Resolver: v.NewJSONSchemaCachingResolver(
        v.JSONSchemaResolverFunc(func(ctx context.Context, url string) ([]byte, error) {
            return loadSchemaResource(ctx, url)
        }),
    ),

    AdditionalPropertiesFalsePolicy: &policy,
})

Resources preloads a closed schema graph without I/O. Compilation is closed-world by default: unresolved external references do not read the filesystem or network. Set Resolver explicitly to resolve them. Built-in resolver helpers include JSONSchemaResourceMap, JSONSchemaResolverChain, JSONSchemaCachingResolver, and the root-constrained JSONSchemaFileResolver.

For cancellable resolution/compilation use CompileJSONSchemaContext or CompileJSONSchemaContextWithOptions. Cancellation is checked around library-controlled work and is propagated into resolvers; the underlying JSON Schema engine does not expose an interrupt hook in the middle of one synchronous compile/validate call. HTTP(S) fetching is deliberately not enabled implicitly.

RegexpTimeout limits one ECMAScript regexp match. The default value 0 preserves unlimited matching for full compatibility; set a positive duration when validating against untrusted schemas.

Custom formats, content encodings, content media types, and vocabularies are registered through yamlvalidator-owned types, so callers do not need to import the underlying JSON Schema engine:

schema, err := v.CompileJSONSchemaWithOptions(schemaJSON, v.JSONSchemaCompileOptions{
    AssertContent: true,
    ContentEncodings: []v.JSONSchemaContentEncoding{
        {
            Name:   "my-encoding",
            Decode: decodeMyEncoding,
        },
    },
    ContentMediaTypes: []v.JSONSchemaContentMediaType{
        {
            Name:     "application/x-example",
            Validate: validateExampleMediaType,
        },
    },
})
Functional JSON Schema extensions

For common extension cases, yamlvalidator exposes its own API so callers do not need to depend directly on the underlying JSON Schema engine.

A custom format is useful for scalar validation and can also validate mapping keys through propertyNames:

schema, err := v.CompileJSONSchemaWithOptions(schemaJSON, v.JSONSchemaCompileOptions{
    AssertFormat: true,
    Formats: []v.JSONSchemaFormat{
        {
            Name: "module-name",
            Validate: func(value any) error {
                name, ok := value.(string)
                if ok && !validModuleName(name) {
                    return fmt.Errorf("invalid module name")
                }
                return nil
            },
        },
    },
})

The schema can then use {"format":"module-name"} or {"propertyNames":{"format":"module-name"}}.

For arbitrary business logic, register a functional custom keyword. The simplest form is literally a validation function receiving the keyword value from the schema and the current instance value:

keyword := v.JSONSchemaKeyword{
    Name: "x-require-property",
    Validate: func(raw, instance any, ctx *v.JSONSchemaKeywordValidationContext) {
        property, ok := raw.(string)
        if !ok {
            ctx.AddError("x-require-property expects a string")
            return
        }
        object, ok := instance.(map[string]any)
        if !ok {
            return
        }

        ctx.MarkPropertyEvaluated(property)
        if _, ok := object[property]; !ok {
            ctx.AddErrorAt([]string{property}, "required by x-require-property")
        }
    },
}

schema, err := v.CompileJSONSchemaWithOptions(schemaJSON, v.JSONSchemaCompileOptions{
    Keywords: []v.JSONSchemaKeyword{keyword},
})

If keyword configuration needs parsing or validation, use Compile instead of Validate; it receives the keyword value once at schema compilation time and returns a JSONSchemaKeywordValidateFunc for subsequent instance validation.

Keywords that contain nested schemas can use CompileWithContext instead of importing the underlying engine. Declare where nested schemas may occur, compile exact branches with Subschema or Reference, then validate them through ValidateSubschema:

keyword := v.JSONSchemaKeyword{
    Name: "x-dispatch",
    Subschemas: []v.JSONSchemaSubschemaPath{
        {v.JSONSchemaSubschemaAllProperties()},
    },
    CompileWithContext: func(
        ctx *v.JSONSchemaKeywordCompileContext,
        raw any,
    ) (v.JSONSchemaKeywordValidateFunc, error) {
        config := raw.(map[string]any)
        branches := make(map[string]*v.JSONSchemaSubschema, len(config))
        for name := range config {
            branches[name] = ctx.Subschema(name)
        }

        return func(instance any, validation *v.JSONSchemaKeywordValidationContext) {
            object, _ := instance.(map[string]any)
            kind, _ := object["kind"].(string)
            if branch := branches[kind]; branch != nil {
                validation.ValidateSubschema(branch, instance, nil)
            } else {
                validation.AddErrorAt([]string{"kind"}, "unknown kind")
            }
        }, nil
    },
}

Subschema location helpers cover an exact property, all property values, an exact array item, or all array items. Nested schemas keep normal JSON Schema reference semantics, including $ref.

JSONSchemaKeywordValidationContext supports multiple diagnostics through AddError / AddErrorAt and integrates with unevaluatedProperties / unevaluatedItems through MarkPropertyEvaluated / MarkItemEvaluated. Relative issue paths are mapped back to the corresponding YAML line and column, and the keyword name becomes the diagnostic Code.

For a named set of keywords use JSONSchemaVocabulary{URL, Keywords} through JSONSchemaCompileOptions.Vocabularies. First-class functional vocabularies are activated for that compilation automatically. Set JSONSchemaVocabulary.Schema when the vocabulary should validate the shape of its own keyword declarations before compiling the instance schema.

Custom keyword validators operate on the JSON data model (map[string]any, []any, json.Number, strings, booleans, null), not on yaml.Node. Treat the supplied instance as read-only; compiled schemas may be reused concurrently, so captured validator state must be concurrency-safe. YAML-specific validation that needs tags/styles/comments should continue to use native ValueValidator / KeyValidator.

Format and content assertions

For 2019-09 and 2020-12, format remains annotation-only unless the schema vocabulary requires assertions or AssertFormat is enabled. The validator supplies stricter implementations for email, hostname, IPv4, duration, URI, URI-reference, URI-template, idn-email, and idn-hostname, and uses an ECMAScript-compatible regexp engine for JSON Schema patterns and regex format validation.

AssertContent enables contentEncoding, contentMediaType, and contentSchema assertions supported by the engine.

YAML to JSON data model

JSON Schema validates the JSON data model. During validation yamlvalidator converts the YAML AST without losing source locations:

  • YAML mappings become JSON objects; mapping keys therefore must be strings.
  • YAML sequences become JSON arrays.
  • YAML integers and finite floating-point values are converted using exact textual numbers rather than float64 round-tripping.
  • YAML hexadecimal, binary, octal, and legacy octal integers are normalized to their mathematical JSON integer value.
  • YAML aliases and merge keys are resolved before JSON Schema validation.
  • YAML .nan and .inf are rejected because JSON has no non-finite numeric values.
  • YAML custom-tagged scalar values are represented as their scalar string value.

Diagnostics preserve the YAML path, line, column, JSON Schema keyword in Code, and originating schema location in SchemaPath.

Conformance

The JSON Schema adapter is exercised in CI against the official JSON-Schema-Test-Suite using the public CompileJSONSchema and YAML validation path:

  • draft-04: 618/618 core tests
  • draft-06: 841/841 core tests
  • draft-07: 929/929 core tests
  • 2019-09: 1261/1261 core tests
  • 2020-12: 1301/1301 core tests
  • total: 4950/4950 core tests

The same public API also passes 3884/3885 official optional tests when JSON string values are represented losslessly through YAML escapes where necessary. The single remaining optional draft-04 case is zeroTerminatedFloats, which intentionally tests host-language numeric type distinctions by expecting JSON 1.0 not to satisfy integer. yamlvalidator follows the engine's mathematical JSON Schema numeric semantics, where an exactly integral numeric value satisfies integer.

Optional coverage includes ECMAScript pattern semantics, email, idn-email, hostname, idn-hostname, duration, URI, URI-reference, URI-template, content assertions, and format-regex validation. Raw YAML still obeys YAML's own character restrictions; code points such as U+0085 or U+FFFF can be supplied through YAML escapes when a JSON Schema format test needs those exact scalar values.

AdditionalPropertiesFalsePolicy is a yamlvalidator presentation option: it can downgrade or suppress a direct additionalProperties: false diagnostic for editor-style workflows. It does not rewrite JSON Schema combinator semantics.

Built-in Validators

Value Validators
// Enum validation
EnumValidator{Allowed: []string{"v1", "v2", "v3"}}

// Regex validation
RegexValidator{
    Pattern: regexp.MustCompile(`^[a-z]+$`),
    Message: "must be lowercase letters",
}

// Numeric range. YAML input is compared exactly (no float64 round-trip).
RangeValidator{Min: v.Ptr[float64](1), Max: v.Ptr[float64](100)}

// Exact bounds for values that cannot be represented safely as float64.
RangeValidator{
    MinExact: MustExactNumber("9007199254740993"),
}

// Non-empty check
NonEmptyValidator{}

// Length validation
LengthValidator{Min: v.Ptr[int](1), Max: v.Ptr[int](255)}

// URL validation
URLValidator{RequireScheme: true, AllowedSchemes: []string{"http", "https"}}
Key Validators
// Regex key validation
RegexKeyValidator{
    Pattern: regexp.MustCompile(`^[a-z][a-z0-9._-]*$`),
    Message: "invalid key format",
}

// Forbidden keys
ForbiddenKeyValidator{Forbidden: []string{"password", "secret"}}

// Key length
LengthKeyValidator{Min: v.Ptr[int](1), Max: v.Ptr[int](63)}

Inter-field Logic

AnyOf (at least one group)
// Either configFile, OR both host AND port
AnyOf: [][]string{{"configFile"}, {"host", "port"}}
ExactlyOneOf (exactly one field)
// Exactly one of inline/file/url
ExactlyOneOf: []string{"inline", "file", "url"}
MutuallyExclusive (at most one)
// debug and quiet cannot both be present
MutuallyExclusive: []string{"debug", "quiet"}
Conditional Rules
Conditions: []ConditionalRule{
    {
        ConditionField: "type",
        ConditionValue: "external",
        ThenRequired:   []string{"endpoint"},
        ThenForbidden:  []string{"local"},
    },
}

Validation Options

result := validator.ValidateWithOptions(yaml, ValidationContext{
    StrictKeys:     true,  // Unknown keys are errors for native FieldSchema
    StopOnFirst:    false, // Continue after first error
    StrictTypes:    false, // Parse values for native FieldSchema type inference
    YAML11Booleans: false, // Plain YAML 1.1 yes/no/on/off compatibility

    MaxBytes:       2 << 20, // 2 MiB; 0 = unlimited
    MaxDocuments:   10,      // 0 = unlimited
    MaxDepth:       100,     // root value has depth 1; 0 = unlimited
    MaxDiagnostics: 100,     // 0 = unlimited
})
if result.Truncated {
    // MaxDiagnostics was reached.
}

For cancellation/deadlines use the context-aware API:

runCtx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()

result, err := validator.ValidateContextWithOptions(runCtx, yaml, ValidationContext{
    MaxDepth: 100,
})
if errors.Is(err, context.DeadlineExceeded) {
    // result may contain diagnostics collected before cancellation.
}

Cancellation is cooperative. Native traversal and custom validators can observe it through ValidationContext.Context(). A custom validator performing blocking work should select on or pass that context to the operation. Cancellation is checked around YAML traversal/conversion and JSON Schema validation, but it cannot interrupt an already-running yaml.Decoder.Decode call or an in-progress validation call inside the underlying JSON Schema engine.

CLI

The CLI supports both the native serialized FieldSchema format and standards-compliant JSON Schema. Native schemas are compiled and checked for definition errors before validation.

Native FieldSchema:

go run ./cmd/yamlvalidator \
  -schema /tmp/schema.yaml \
  -schema-format field \
  -file ./path/to/config.yaml \
  -strict-keys

Standard JSON Schema, including relative file $ref resolution from the schema file location:

go run ./cmd/yamlvalidator \
  -schema ./schemas/config.schema.json \
  -schema-format jsonschema \
  -file ./config.yaml \
  -assert-format \
  -regexp-timeout 500ms

JSON Schema CLI options: -json-schema-draft, -assert-format, -assert-content, -assert-vocabs, and -regexp-timeout. Validation safety limits are exposed as -max-bytes, -max-documents, -max-depth, and -max-diagnostics. Existing options include -stop-on-first, -yaml11-bools, -sort, plus native-schema-only -strict-keys and -strict-types.

Error Handling

Error Levels
  • LevelError - Critical validation failures
  • LevelWarning - Non-critical issues (deprecated fields, unknown keys in permissive mode)
Error Formatting
result := validator.ValidateBytes(yaml)

// Get all errors
for _, err := range result.Collector.Errors() {
    fmt.Println(err)
}

// Format with source context
fmt.Println(result.FormatAll(true)) // true = sort by position
Example Output
[ERROR] line 2:13: invalid value "v3" (expected one of [v1 v1beta1 apps/v1], got v3) (path: apiVersion)
     1 |
>    2 | apiVersion: v3
       |             ^
     3 | kind: Deployment

[ERROR] line 5:9: must be lowercase DNS-compatible name (got MyApp) (path: metadata.name)
     4 | metadata:
>    5 |   name: MyApp
       |         ^
     6 |   namespace: production

Multi-Document Support

The validator automatically handles multi-document YAML (separated by ---):

name: first
---
name: second
---
name: third

Errors in subsequent documents are prefixed with doc[N].:

[ERROR] line 5:1: required field "name" is missing (path: doc[2].name)

Custom Validators

Value Validator
type MyValidator struct{}

func (v MyValidator) Validate(node *yaml.Node, path string, ctx *ValidationContext) {
    if node.Value != "expected" {
        ctx.AddError(ValidationError{
            Level:   LevelError,
            Path:    path,
            Line:    node.Line,
            Column:  node.Column,
            Message: "value is not expected",
            Got:     node.Value,
        })
    }
}
Key Validator
type MyKeyValidator struct{}

func (v MyKeyValidator) ValidateKey(key string, keyNode *yaml.Node, path string, ctx *ValidationContext) {
    if strings.HasPrefix(key, "_") {
        ctx.AddError(ValidationError{
            Level:   LevelWarning,
            Path:    path,
            Line:    keyNode.Line,
            Column:  keyNode.Column,
            Message: "keys starting with underscore are reserved",
            Got:     key,
        })
    }
}

Custom validators may be invoked concurrently when the same compiled validator is reused by multiple goroutines. Keep validator state immutable or synchronize it explicitly. Built-in validators snapshot their configuration during CompileFieldSchema; a configurable custom validator can opt into the same behavior by implementing ValueValidatorCloner or KeyValidatorCloner. For cancellable I/O or other blocking work, propagate ctx.Context().

When a custom validator reports an error for a child node, use AppendPropertyPath and AppendIndexPath instead of concatenating strings manually. They preserve unambiguous paths for property names containing dots, brackets, or numeric-looking names.

Best Practices

1. Use AdditionalProperties for arbitrary keys
// Allow any string values for unknown keys
labels: {
    Type:                 TypeMap,
    AdditionalProperties: &FieldSchema{Type: TypeString},
}
2. Combine with key validators
labels: {
    Type:                 TypeMap,
    AdditionalProperties: &FieldSchema{Type: TypeString},
    KeyValidators: []KeyValidator{
        RegexKeyValidator{Pattern: regexp.MustCompile(`^[a-z][a-z0-9._-]*$`)},
    },
}
3. Use Nullable for optional fields that can be explicitly null
timeout: {
    Type:     TypeInt,
    Nullable: true, // Allows: timeout: null
}
4. Use helper functions for pointers
MinItems: Ptr[int](1)
Max:      Ptr[float64](100)

API Reference

Validator
// Preferred for native schemas assembled dynamically
v, err := CompileFieldSchema(schema)

// Backwards-compatible constructor for an already trusted schema
v := NewValidator(schema)

// Validate bytes
result := v.ValidateBytes(yamlData)

// Validate with options
result := v.ValidateWithOptions(yamlData, ValidationContext{...})

// Context-aware validation
result, err := v.ValidateContext(ctx, yamlData)
result, err := v.ValidateContextWithOptions(ctx, yamlData, ValidationContext{...})

// Reader-based validation. MaxBytes reads at most MaxBytes+1 bytes.
result, err := v.ValidateReader(reader)
result, err := v.ValidateReaderWithOptions(reader, ValidationContext{...})
result, err := v.ValidateReaderContext(ctx, reader)
result, err := v.ValidateReaderContextWithOptions(ctx, reader, ValidationContext{...})
ValidationResult
result.HasErrors()              // bool
result.Collector.Errors()       // []ValidationError
result.Collector.Warnings()     // []ValidationError
result.Collector.All()          // []ValidationError in collection order
result.SortByPosition()         // Sort by line/column
result.FormatAll(sortByPos)     // Format with source context
result.Truncated                // true if MaxDiagnostics stopped validation
result.Canceled                 // true if context canceled/deadline expired
result.ContextErr               // context.Canceled / context.DeadlineExceeded
ValidationError
type ValidationError struct {
    Level      ErrorLevel
    Code       string      // Machine-readable code, e.g. "required" or "minimum"
    SchemaPath string      // Originating JSON Schema location when available
    Path       string      // Stable display path, e.g. "spec.containers[0].image"
    PathTokens []PathToken // Typed property/index/document components
    Line       int         // 1-based (0 if unknown)
    Column     int         // 1-based (0 if unknown)
    Message    string
    Got        string
    Expected   string
    Details    any         // Optional typed machine-readable details
}

Details is populated where a diagnostic has useful structured data. Current detail types include RequiredDetails, UnknownKeyDetails, TypeMismatchDetails, NumericRangeDetails, ItemCountDetails, and DependencyDetails. PathTokens avoids parsing the human-readable Path; the leading doc[N] syntax is reserved for multi-document YAML and is represented by PathTokenDocument.

The collector accessors return defensive copies, so callers may sort or modify returned diagnostics without mutating the stored validation result.

Benchmarks

The repository includes allocation-aware benchmarks for native schema compilation, native small/large validation, JSON Schema compilation, and JSON Schema small/large validation:

go test -run '^$' -bench='Benchmark(Native|JSONSchema)' -benchmem .

Benchmarks are intended for before/after regression work rather than fixed CI timing thresholds. Large-document validation avoids per-source-line string allocations by sharing one backing source string.

API stability

v1.0.0 is the first SemVer-stable release. Its public API is frozen against the v0.6.0 baseline, and CI runs golang.org/x/exp/apidiff against that tag to reject incompatible changes across all public packages. Backward-compatible additions remain possible within v1; removals or signature/type changes require a new major version.

License

Apache License 2.0

Documentation

Overview

Package yamlvalidator provides a flexible YAML validation library with support for type checking, custom validators, conditional logic, and detailed error reporting with source context.

Index

Constants

This section is empty.

Variables

View Source
var ErrJSONSchemaResourceNotFound = errors.New("JSON Schema resource not found")

ErrJSONSchemaResourceNotFound allows resolver chains to distinguish a miss from an actual resolver failure.

View Source
var ErrJSONSchemaResourceOutsideRoot = errors.New("JSON Schema resource is outside resolver root")

ErrJSONSchemaResourceOutsideRoot is returned by JSONSchemaFileResolver when a file URL escapes its configured root.

Functions

func AppendIndexPath added in v0.6.0

func AppendIndexPath(base string, index int) (string, error)

AppendIndexPath appends a non-negative sequence index to a stable display path. It returns an error for negative indexes.

func AppendPropertyPath added in v0.6.0

func AppendPropertyPath(base, property string) string

AppendPropertyPath appends a mapping property to a stable display path. Ambiguous property names are quoted automatically.

func FormatErrorWithSource

func FormatErrorWithSource(err ValidationError, lines []string) string

FormatErrorWithSource formats an error with source context. Correctly handles tabs and Unicode.

func FormatPathTokens added in v0.4.0

func FormatPathTokens(tokens []PathToken) string

FormatPathTokens formats typed path tokens using the library's stable display syntax.

func Ptr

func Ptr[T any](v T) *T

Ptr returns a pointer to the value. Useful for setting Min/Max fields.

func RenderLineWithCaret

func RenderLineWithCaret(line string, byteCol int) (string, int, int)

RenderLineWithCaret is an exported wrapper useful for external tests and tools.

func ValidateFieldSchema added in v0.3.0

func ValidateFieldSchema(schema *FieldSchema) error

ValidateFieldSchema checks FieldSchema invariants, including nested schemas, invalid constraints, recursive schema graphs, and validator definitions.

Types

type ConditionalRule

type ConditionalRule struct {
	// ConditionField is the field to check.
	ConditionField string
	// ConditionValue is the expected value (scalar comparison).
	ConditionValue string
	// ThenRequired lists fields that become required when condition is met.
	ThenRequired []string
	// ThenForbidden lists fields that are forbidden when condition is met.
	ThenForbidden []string
}

ConditionalRule defines conditional validation logic. When ConditionField equals ConditionValue, additional requirements apply.

type DefinitionValidator added in v0.3.0

type DefinitionValidator interface {
	ValidateDefinition() error
}

DefinitionValidator may be implemented by value/key validators that can validate their own configuration during FieldSchema compilation.

type DependencyDetails added in v0.4.0

type DependencyDetails struct {
	Field   string
	Trigger string
}

DependencyDetails describes a field required by another field.

type ErrorCollector

type ErrorCollector struct {
	// contains filtered or unexported fields
}

ErrorCollector accumulates validation errors and warnings.

func NewErrorCollector

func NewErrorCollector() *ErrorCollector

NewErrorCollector creates a new empty ErrorCollector.

func (*ErrorCollector) Add

func (c *ErrorCollector) Add(err ValidationError)

Add adds a validation error to the collector.

func (*ErrorCollector) All

func (c *ErrorCollector) All() []ValidationError

All returns a defensive copy of all diagnostics in insertion order.

func (*ErrorCollector) Errors

func (c *ErrorCollector) Errors() []ValidationError

Errors returns a defensive copy of all errors.

func (*ErrorCollector) HasErrors

func (c *ErrorCollector) HasErrors() bool

HasErrors returns true if there are any errors (not warnings).

func (*ErrorCollector) Warnings

func (c *ErrorCollector) Warnings() []ValidationError

Warnings returns a defensive copy of all warnings.

type ErrorLevel

type ErrorLevel int

ErrorLevel defines the severity of a validation error.

const (
	// LevelWarning indicates a non-critical issue (e.g., deprecated field, unknown key in permissive mode).
	LevelWarning ErrorLevel = iota
	// LevelError indicates a critical validation failure.
	LevelError
)

func (ErrorLevel) String

func (l ErrorLevel) String() string

type FieldSchema

type FieldSchema struct {
	// Type is the expected node type.
	Type NodeType

	// AllowedTypes accepts any of the listed node types. When non-empty it
	// takes precedence over Type and is useful for schema unions.
	AllowedTypes []NodeType

	// Required indicates the field must be present.
	Required bool

	// Nullable allows null values even when Type is not TypeNull.
	Nullable bool

	// Deprecated contains a deprecation message (empty = not deprecated).
	// Use "true" for a generic message.
	Deprecated string

	// Description is a human-readable field description.
	Description string

	// Default is the default value. If set and field is missing, a warning is emitted.
	Default interface{}

	// AllowedKeys defines known keys and their schemas.
	// If nil, ALL keys are considered unknown.
	// This does NOT mean "don't check" - it means "no known keys".
	//
	// For "any keys allowed, no validation":
	//   AllowedKeys: nil,
	//   AdditionalProperties: &FieldSchema{Type: TypeAny},
	//
	// For "don't touch this map at all":
	//   AllowedKeys: nil,
	//   AdditionalProperties: nil,
	//   UnknownKeyPolicy: UnknownKeyIgnore,
	AllowedKeys map[string]*FieldSchema

	// AdditionalProperties is the schema for keys not in AllowedKeys.
	// If not nil: unknown keys are allowed and validated against this schema.
	// If nil: unknown keys are handled by UnknownKeyPolicy.
	AdditionalProperties *FieldSchema

	// UnknownKeyPolicy determines handling of keys not in AllowedKeys
	// when AdditionalProperties is nil.
	UnknownKeyPolicy UnknownKeyPolicy

	// KeyValidators validate key names (applied to ALL keys).
	KeyValidators []KeyValidator

	// ItemSchema is the schema for sequence items.
	ItemSchema *FieldSchema

	// MinItems is the minimum number of items (nil = no limit).
	MinItems *int

	// MaxItems is the maximum number of items (nil = no limit).
	MaxItems *int

	// Validators are custom value validators.
	Validators []ValueValidator

	// AnyOf requires at least one field group to be fully present.
	// Example: [][]string{{"configFile"}, {"host", "port"}}
	// Means: either configFile, OR both host AND port.
	AnyOf [][]string

	// ExactlyOneOf requires exactly one field from the list.
	// Example: []string{"inline", "file", "url"}
	// Means: exactly one of inline/file/url must be present.
	ExactlyOneOf []string

	// MutuallyExclusive allows at most one field from the list (zero is OK).
	// Example: []string{"debug", "quiet"}
	// Means: debug and quiet cannot both be present.
	MutuallyExclusive []string

	// Conditions define conditional validation rules.
	Conditions []ConditionalRule

	// OneOfSchemas requires exactly one child schema to validate successfully.
	OneOfSchemas []*FieldSchema

	// AnyOfSchemas requires at least one child schema to validate successfully.
	AnyOfSchemas []*FieldSchema

	// OneOfRequired requires exactly one field group to be fully present.
	OneOfRequired [][]string

	// ForbiddenTogether rejects groups whose fields are all present together.
	ForbiddenTogether [][]string

	// DependentRequired requires additional fields when a trigger field is present.
	DependentRequired map[string][]string
}

FieldSchema defines the validation rules for a field.

func CompileJSONSchema added in v0.3.0

func CompileJSONSchema(data []byte) (*FieldSchema, error)

CompileJSONSchema compiles a JSON Schema using draft 2020-12 as the default dialect. Schemas declaring $schema are compiled using their declared dialect.

func CompileJSONSchemaContext added in v0.5.0

func CompileJSONSchemaContext(ctx context.Context, data []byte) (*FieldSchema, error)

CompileJSONSchemaContext is the context-aware form of CompileJSONSchema. Context cancellation is observed by library-controlled compilation work and by JSONSchemaResolver implementations.

func CompileJSONSchemaContextWithOptions added in v0.5.0

func CompileJSONSchemaContextWithOptions(
	ctx context.Context,
	data []byte,
	opts JSONSchemaCompileOptions,
) (*FieldSchema, error)

CompileJSONSchemaContextWithOptions is the context-aware form of CompileJSONSchemaWithOptions.

func CompileJSONSchemaWithOptions added in v0.3.0

func CompileJSONSchemaWithOptions(data []byte, opts JSONSchemaCompileOptions) (*FieldSchema, error)

CompileJSONSchemaWithOptions compiles a standards-compliant JSON Schema and returns a FieldSchema adapter that validates YAML through the JSON Schema engine while preserving YAML source positions in diagnostics.

type ItemCountDetails added in v0.4.0

type ItemCountDetails struct {
	Actual int
	Bound  int
}

ItemCountDetails describes a sequence length failure.

type JSONSchemaCachingResolver added in v0.5.0

type JSONSchemaCachingResolver struct {
	// contains filtered or unexported fields
}

JSONSchemaCachingResolver caches successful resolutions. Returned byte slices are defensive copies.

func NewJSONSchemaCachingResolver added in v0.5.0

func NewJSONSchemaCachingResolver(resolver JSONSchemaResolver) *JSONSchemaCachingResolver

NewJSONSchemaCachingResolver wraps resolver with a concurrency-safe cache.

func (*JSONSchemaCachingResolver) Resolve added in v0.5.0

func (resolver *JSONSchemaCachingResolver) Resolve(
	ctx context.Context,
	resourceURL string,
) ([]byte, error)

Resolve implements JSONSchemaResolver.

type JSONSchemaCompileOptions added in v0.3.0

type JSONSchemaCompileOptions struct {
	// SchemaURL is the retrieval URL of the root schema. It is used as the base
	// URI for relative references when the schema does not establish another base
	// with $id. The default is an in-memory HTTPS URL.
	SchemaURL string

	// DefaultDraft is used only when the schema does not contain $schema.
	// The default is draft 2020-12.
	DefaultDraft JSONSchemaDraft

	// AssertFormat forces format to be an assertion even in dialects where it is
	// annotation-only by default.
	AssertFormat bool

	// AssertContent enables contentEncoding/contentMediaType/contentSchema assertions.
	AssertContent bool

	// AssertVocabs requires vocabularies declared by a metaschema to be known.
	AssertVocabs bool

	// RegexpTimeout bounds one ECMAScript regexp match. Zero preserves the
	// regexp engine's unlimited default. Use a positive duration for untrusted schemas.
	RegexpTimeout time.Duration

	// Formats registers first-class functional custom formats.
	Formats []JSONSchemaFormat

	// ContentEncodings registers custom contentEncoding decoders.
	ContentEncodings []JSONSchemaContentEncoding

	// ContentMediaTypes registers custom contentMediaType validators.
	ContentMediaTypes []JSONSchemaContentMediaType

	// Keywords registers functional custom keywords in an internal vocabulary.
	// They are activated for this compilation automatically.
	Keywords []JSONSchemaKeyword

	// Vocabularies registers named functional custom vocabularies. They are
	// activated for this compilation automatically.
	Vocabularies []JSONSchemaVocabulary

	// Resources preloads external resources addressed by their retrieval URLs.
	// This is the preferred way to compile a closed schema graph without I/O.
	Resources map[string][]byte

	// Resolver resolves unresolved external references. If nil, compilation is
	// closed-world: only the root schema, Resources, and built-in metaschemas are
	// available. No filesystem or network I/O is performed implicitly.
	Resolver JSONSchemaResolver

	// AdditionalPropertiesFalsePolicy optionally downgrades direct
	// additionalProperties:false diagnostics. This is a presentation policy and
	// intentionally does not rewrite JSON Schema combinator semantics.
	AdditionalPropertiesFalsePolicy *UnknownKeyPolicy
}

JSONSchemaCompileOptions controls JSON Schema compilation and validation.

type JSONSchemaContentEncoding added in v0.6.0

type JSONSchemaContentEncoding struct {
	Name   string
	Decode func(string) ([]byte, error)
}

JSONSchemaContentEncoding registers a custom JSON Schema contentEncoding.

type JSONSchemaContentMediaType added in v0.6.0

type JSONSchemaContentMediaType struct {
	Name          string
	Validate      func([]byte) error
	UnmarshalJSON func([]byte) (any, error)
}

JSONSchemaContentMediaType registers a custom JSON Schema contentMediaType. UnmarshalJSON is optional and should be set only when the media type contains a JSON-compatible data model that contentSchema may validate.

type JSONSchemaDraft added in v0.3.0

type JSONSchemaDraft string

JSONSchemaDraft selects the default JSON Schema dialect used when a schema does not declare $schema. An explicit $schema in the document takes precedence.

const (
	JSONSchemaDraft4    JSONSchemaDraft = "draft-04"
	JSONSchemaDraft6    JSONSchemaDraft = "draft-06"
	JSONSchemaDraft7    JSONSchemaDraft = "draft-07"
	JSONSchemaDraft2019 JSONSchemaDraft = "2019-09"
	JSONSchemaDraft2020 JSONSchemaDraft = "2020-12"
)

type JSONSchemaFileResolver added in v0.5.0

type JSONSchemaFileResolver struct {
	// contains filtered or unexported fields
}

JSONSchemaFileResolver resolves file:// resources confined to one directory. The root must exist when the resolver is created.

func NewJSONSchemaFileResolver added in v0.5.0

func NewJSONSchemaFileResolver(root string) (*JSONSchemaFileResolver, error)

NewJSONSchemaFileResolver creates a file resolver constrained to root.

func (*JSONSchemaFileResolver) Resolve added in v0.5.0

func (resolver *JSONSchemaFileResolver) Resolve(
	ctx context.Context,
	resourceURL string,
) ([]byte, error)

Resolve implements JSONSchemaResolver.

type JSONSchemaFormat added in v0.3.0

type JSONSchemaFormat struct {
	Name     string
	Validate func(value any) error
}

JSONSchemaFormat registers a custom JSON Schema format without exposing the underlying JSON Schema engine API.

type JSONSchemaKeyword added in v0.3.0

type JSONSchemaKeyword struct {
	Name               string
	Validate           JSONSchemaKeywordFunc
	Compile            JSONSchemaKeywordCompileFunc
	CompileWithContext JSONSchemaKeywordCompileContextFunc
	Subschemas         []JSONSchemaSubschemaPath
}

JSONSchemaKeyword defines one custom JSON Schema keyword. Set exactly one of Validate, Compile, or CompileWithContext. Subschemas declares locations of nested schemas relative to the keyword value.

type JSONSchemaKeywordCompileContext added in v0.5.0

type JSONSchemaKeywordCompileContext struct {
	// contains filtered or unexported fields
}

JSONSchemaKeywordCompileContext exposes high-level helpers needed by custom keywords which contain nested schemas.

func (*JSONSchemaKeywordCompileContext) Reference added in v0.5.0

Reference compiles a schema reference using the current schema resource.

func (*JSONSchemaKeywordCompileContext) Subschema added in v0.5.0

Subschema compiles a nested schema located at path relative to the custom keyword value. Path components are JSON object keys or array indexes encoded as decimal strings.

type JSONSchemaKeywordCompileContextFunc added in v0.5.0

type JSONSchemaKeywordCompileContextFunc func(
	ctx *JSONSchemaKeywordCompileContext,
	keywordValue any,
) (JSONSchemaKeywordValidateFunc, error)

JSONSchemaKeywordCompileContextFunc is the advanced high-level compile form for keywords that contain nested schemas or schema references.

type JSONSchemaKeywordCompileFunc added in v0.3.0

type JSONSchemaKeywordCompileFunc func(
	keywordValue any,
) (JSONSchemaKeywordValidateFunc, error)

JSONSchemaKeywordCompileFunc compiles a keyword value from the schema into a runtime validation function. It is useful for parsing/validating keyword configuration once instead of on every validation call.

type JSONSchemaKeywordFunc added in v0.3.0

type JSONSchemaKeywordFunc func(
	keywordValue any,
	instance any,
	ctx *JSONSchemaKeywordValidationContext,
)

JSONSchemaKeywordFunc is the simple custom-keyword form. The schema keyword value and current JSON instance value are supplied on each validation call.

type JSONSchemaKeywordValidateFunc added in v0.3.0

type JSONSchemaKeywordValidateFunc func(
	instance any,
	ctx *JSONSchemaKeywordValidationContext,
)

JSONSchemaKeywordValidateFunc validates one JSON instance value.

type JSONSchemaKeywordValidationContext added in v0.3.0

type JSONSchemaKeywordValidationContext struct {
	// contains filtered or unexported fields
}

JSONSchemaKeywordValidationContext collects custom keyword diagnostics and evaluation annotations during one keyword validation call.

func (*JSONSchemaKeywordValidationContext) AddError added in v0.3.0

func (ctx *JSONSchemaKeywordValidationContext) AddError(message string)

AddError reports an error for the current instance value.

func (*JSONSchemaKeywordValidationContext) AddErrorAt added in v0.3.0

func (ctx *JSONSchemaKeywordValidationContext) AddErrorAt(path []string, message string)

AddErrorAt reports an error at a path relative to the current instance value.

func (*JSONSchemaKeywordValidationContext) MarkItemEvaluated added in v0.3.0

func (ctx *JSONSchemaKeywordValidationContext) MarkItemEvaluated(index int)

MarkItemEvaluated marks an array item as evaluated for unevaluatedItems semantics.

func (*JSONSchemaKeywordValidationContext) MarkPropertyEvaluated added in v0.3.0

func (ctx *JSONSchemaKeywordValidationContext) MarkPropertyEvaluated(name string)

MarkPropertyEvaluated marks an object property as evaluated for unevaluatedProperties semantics.

func (*JSONSchemaKeywordValidationContext) ValidateSubschema added in v0.5.0

func (ctx *JSONSchemaKeywordValidationContext) ValidateSubschema(
	schema *JSONSchemaSubschema,
	instance any,
	relativePath []string,
) bool

ValidateSubschema validates instance with a nested schema and reports any resulting JSON Schema errors through the current validation context. relativePath is relative to the current instance value.

type JSONSchemaResolver added in v0.5.0

type JSONSchemaResolver interface {
	Resolve(ctx context.Context, url string) ([]byte, error)
}

JSONSchemaResolver resolves an absolute JSON Schema retrieval URL. Implementations must be safe for concurrent use if a compile configuration is reused concurrently.

type JSONSchemaResolverChain added in v0.5.0

type JSONSchemaResolverChain []JSONSchemaResolver

JSONSchemaResolverChain tries resolvers in order. Only ErrJSONSchemaResourceNotFound advances to the next resolver. Treat the slice as immutable while it is in use.

func (JSONSchemaResolverChain) Resolve added in v0.5.0

func (chain JSONSchemaResolverChain) Resolve(ctx context.Context, resourceURL string) ([]byte, error)

Resolve implements JSONSchemaResolver.

type JSONSchemaResolverFunc added in v0.5.0

type JSONSchemaResolverFunc func(context.Context, string) ([]byte, error)

JSONSchemaResolverFunc adapts a function to JSONSchemaResolver.

func (JSONSchemaResolverFunc) Resolve added in v0.5.0

func (f JSONSchemaResolverFunc) Resolve(ctx context.Context, url string) ([]byte, error)

Resolve implements JSONSchemaResolver.

type JSONSchemaResourceMap added in v0.5.0

type JSONSchemaResourceMap map[string][]byte

JSONSchemaResourceMap is an in-memory resolver keyed by absolute retrieval URL. Treat the map as immutable while it is in use; resolved byte slices are copied.

func (JSONSchemaResourceMap) Resolve added in v0.5.0

func (m JSONSchemaResourceMap) Resolve(ctx context.Context, resourceURL string) ([]byte, error)

Resolve implements JSONSchemaResolver.

type JSONSchemaSubschema added in v0.5.0

type JSONSchemaSubschema struct {
	// contains filtered or unexported fields
}

JSONSchemaSubschema is a compiled nested schema used by custom keywords. Its implementation is intentionally opaque so callers do not depend on the underlying JSON Schema engine.

type JSONSchemaSubschemaPath added in v0.5.0

type JSONSchemaSubschemaPath []JSONSchemaSubschemaPosition

JSONSchemaSubschemaPath declares a nested schema location relative to a custom keyword value.

type JSONSchemaSubschemaPosition added in v0.5.0

type JSONSchemaSubschemaPosition struct {
	// contains filtered or unexported fields
}

JSONSchemaSubschemaPosition identifies one possible nested-schema location inside a custom keyword value. Use the constructor functions below.

func JSONSchemaSubschemaAllItems added in v0.5.0

func JSONSchemaSubschemaAllItems() JSONSchemaSubschemaPosition

JSONSchemaSubschemaAllItems selects all array items.

func JSONSchemaSubschemaAllProperties added in v0.5.0

func JSONSchemaSubschemaAllProperties() JSONSchemaSubschemaPosition

JSONSchemaSubschemaAllProperties selects all object property values.

func JSONSchemaSubschemaItem added in v0.5.0

func JSONSchemaSubschemaItem(index int) JSONSchemaSubschemaPosition

JSONSchemaSubschemaItem selects one array item.

func JSONSchemaSubschemaProperty added in v0.5.0

func JSONSchemaSubschemaProperty(name string) JSONSchemaSubschemaPosition

JSONSchemaSubschemaProperty selects one object property.

type JSONSchemaVocabulary added in v0.3.0

type JSONSchemaVocabulary struct {
	URL string

	// Schema optionally validates the custom keyword declarations introduced by
	// this vocabulary. It must be a self-contained JSON Schema (standard
	// metaschema references are supported).
	Schema []byte

	Keywords []JSONSchemaKeyword
}

JSONSchemaVocabulary groups custom keywords under a vocabulary URL. Vocabularies registered through JSONSchemaCompileOptions are activated for that compilation.

type KeyValidator

type KeyValidator interface {
	ValidateKey(key string, keyNode *yaml.Node, path string, ctx *ValidationContext)
}

KeyValidator validates key names in mappings. The same concurrency contract as ValueValidator applies to stateful implementations.

type KeyValidatorCloner added in v0.4.0

type KeyValidatorCloner interface {
	CloneKeyValidator() KeyValidator
}

KeyValidatorCloner is the key-validator counterpart of ValueValidatorCloner.

type NodeType

type NodeType int

NodeType represents the expected YAML node type.

const (
	// TypeAny accepts any type.
	TypeAny NodeType = iota
	// TypeNull represents null/nil values.
	TypeNull
	// TypeString represents string values.
	TypeString
	// TypeInt represents integer values.
	TypeInt
	// TypeFloat represents floating-point values (also accepts int).
	TypeFloat
	// TypeBool represents boolean values.
	TypeBool
	// TypeMap represents mapping nodes.
	TypeMap
	// TypeSequence represents sequence/array nodes.
	TypeSequence
)

func InferNodeType added in v0.6.0

func InferNodeType(node *yaml.Node, ctx *ValidationContext) NodeType

InferNodeType applies the same YAML type inference used by FieldSchema validation. A nil context uses default type-inference settings.

func (NodeType) String

func (t NodeType) String() string

type NumericRangeDetails added in v0.4.0

type NumericRangeDetails struct {
	Value string
	Bound string
}

NumericRangeDetails describes a numeric bound failure.

type PathToken added in v0.4.0

type PathToken struct {
	Kind  PathTokenKind
	Name  string
	Index int
}

PathToken is one typed component of ValidationError.Path.

func ParsePathTokens added in v0.4.0

func ParsePathTokens(path string) ([]PathToken, error)

ParsePathTokens parses the library's display path syntax into typed tokens.

type PathTokenKind added in v0.4.0

type PathTokenKind string

PathTokenKind identifies one component of a structured validation path.

const (
	PathTokenProperty PathTokenKind = "property"
	PathTokenIndex    PathTokenKind = "index"
	// PathTokenDocument represents the reserved leading doc[N] prefix used for
	// multi-document YAML diagnostics.
	PathTokenDocument PathTokenKind = "document"
)

type RequiredDetails added in v0.4.0

type RequiredDetails struct {
	Field string
}

RequiredDetails describes a missing required field/property.

type TypeMismatchDetails added in v0.4.0

type TypeMismatchDetails struct {
	Expected []string
	Actual   string
}

TypeMismatchDetails describes a type validation failure.

type UnknownKeyDetails added in v0.4.0

type UnknownKeyDetails struct {
	Key        string
	Suggestion string
}

UnknownKeyDetails describes an unknown mapping key and optional suggestion.

type UnknownKeyPolicy

type UnknownKeyPolicy int

UnknownKeyPolicy determines how unknown keys in maps are handled.

const (
	// UnknownKeyInherit uses ctx.StrictKeys to decide:
	//   StrictKeys=true  -> error
	//   StrictKeys=false -> warning
	UnknownKeyInherit UnknownKeyPolicy = iota

	// UnknownKeyError treats unknown keys as errors.
	UnknownKeyError

	// UnknownKeyWarn treats unknown keys as warnings.
	UnknownKeyWarn

	// UnknownKeyIgnore silently ignores unknown keys.
	UnknownKeyIgnore
)

type ValidationContext

type ValidationContext struct {
	// StrictKeys determines the default behavior for unknown keys
	// when UnknownKeyPolicy is UnknownKeyInherit:
	//   true  -> unknown keys are errors
	//   false -> unknown keys are warnings
	StrictKeys bool

	// StopOnFirst stops validation after the first error.
	StopOnFirst bool

	// StrictTypes uses only YAML tags for type inference.
	// When false, values are parsed to infer types (e.g., "123" -> int).
	StrictTypes bool

	// YAML11Booleans enables YAML 1.1 boolean literals (yes/no/on/off).
	// By default, only YAML 1.2 booleans (true/false) are recognized.
	YAML11Booleans bool

	// MaxBytes rejects inputs larger than this many bytes. Zero means unlimited.
	MaxBytes int

	// MaxDocuments limits the number of YAML documents in a stream. Zero means unlimited.
	MaxDocuments int

	// MaxDepth limits YAML container/schema traversal depth. The root value has depth 1.
	// Zero means unlimited.
	MaxDepth int

	// MaxDiagnostics stops validation after this many errors/warnings. Zero means unlimited.
	MaxDiagnostics int
	// contains filtered or unexported fields
}

ValidationContext holds configuration and state for a validation run.

func NewValidationContext

func NewValidationContext() *ValidationContext

NewValidationContext creates a new ValidationContext with default settings.

func (*ValidationContext) AddError

func (ctx *ValidationContext) AddError(err ValidationError)

AddError adds an error to the context's collector.

func (*ValidationContext) Collector

func (ctx *ValidationContext) Collector() *ErrorCollector

Collector returns the error collector.

func (*ValidationContext) Context added in v0.4.0

func (ctx *ValidationContext) Context() context.Context

Context returns the context associated with the current validation run. Custom validators should use it for cancellation/deadline-aware work.

func (*ValidationContext) ContextErr added in v0.4.0

func (ctx *ValidationContext) ContextErr() error

ContextErr reports context cancellation/deadline failure for this run.

func (*ValidationContext) IsStopped

func (ctx *ValidationContext) IsStopped() bool

IsStopped returns true if validation has been stopped by validation policy or by context cancellation/deadline.

type ValidationError

type ValidationError struct {
	Level      ErrorLevel
	Code       string      // Stable machine-readable diagnostic code when available.
	SchemaPath string      // Schema location that produced the diagnostic, when available.
	Path       string      // Stable display path, e.g. "spec.containers[0].image".
	PathTokens []PathToken // Typed path components for programmatic consumers.
	Line       int         // 1-based line number (0 if unknown)
	Column     int         // 1-based column number (0 if unknown)
	Message    string
	Got        string // Actual value/type description
	Expected   string // Expected value/type description
	Details    any    // Optional typed machine-readable diagnostic details.
}

ValidationError represents a single validation issue.

func (ValidationError) Error

func (e ValidationError) Error() string

type ValidationResult

type ValidationResult struct {
	// Collector contains all errors and warnings.
	Collector *ErrorCollector
	// SourceLines contains the original YAML lines.
	SourceLines []string
	// Truncated reports that validation stopped because MaxDiagnostics was reached.
	Truncated bool
	// Canceled reports that validation stopped because its context was canceled
	// or its deadline expired. Context-aware methods also return ContextErr.
	Canceled bool
	// ContextErr is context.Canceled or context.DeadlineExceeded when Canceled is true.
	ContextErr error
}

ValidationResult contains the validation outcome and context for formatting.

func (*ValidationResult) FormatAll

func (r *ValidationResult) FormatAll(sortByPos bool) string

FormatAll formats all errors with source context.

func (*ValidationResult) HasErrors

func (r *ValidationResult) HasErrors() bool

HasErrors returns true if there are any errors.

func (*ValidationResult) SortByPosition

func (r *ValidationResult) SortByPosition()

SortByPosition sorts errors by position in the file.

type Validator

type Validator struct {
	// contains filtered or unexported fields
}

Validator performs YAML validation against a schema.

func CompileFieldSchema added in v0.3.0

func CompileFieldSchema(schema *FieldSchema) (*Validator, error)

CompileFieldSchema validates a native FieldSchema before constructing a Validator. New code should prefer this over NewValidator when schemas are assembled dynamically or loaded from configuration.

func NewValidator

func NewValidator(schema *FieldSchema) *Validator

NewValidator creates a Validator that references the supplied schema directly. Callers must not mutate that schema concurrently with validation. Prefer CompileFieldSchema when an immutable, concurrency-safe schema snapshot is desired.

func (*Validator) ValidateBytes

func (v *Validator) ValidateBytes(data []byte) *ValidationResult

ValidateBytes validates YAML data and returns the result. Supports multi-document YAML (separated by ---).

func (*Validator) ValidateContext added in v0.4.0

func (v *Validator) ValidateContext(runCtx context.Context, data []byte) (*ValidationResult, error)

ValidateContext validates YAML data with cancellation/deadline support. Validation diagnostics remain in the returned result; the error is reserved for context cancellation/deadline.

func (*Validator) ValidateContextWithOptions added in v0.4.0

func (v *Validator) ValidateContextWithOptions(
	runCtx context.Context,
	data []byte,
	opts ValidationContext,
) (*ValidationResult, error)

ValidateContextWithOptions is the context-aware form of ValidateWithOptions.

func (*Validator) ValidateReader added in v0.5.0

func (v *Validator) ValidateReader(reader io.Reader) (*ValidationResult, error)

ValidateReader validates YAML read from reader. Validation failures are returned in ValidationResult; the error is reserved for input I/O failures.

func (*Validator) ValidateReaderContext added in v0.5.0

func (v *Validator) ValidateReaderContext(
	runCtx context.Context,
	reader io.Reader,
) (*ValidationResult, error)

ValidateReaderContext validates YAML from reader with cancellation/deadline support.

func (*Validator) ValidateReaderContextWithOptions added in v0.5.0

func (v *Validator) ValidateReaderContextWithOptions(
	runCtx context.Context,
	reader io.Reader,
	opts ValidationContext,
) (*ValidationResult, error)

ValidateReaderContextWithOptions reads at most MaxBytes+1 bytes when a byte limit is configured, so oversized streams are rejected without unbounded buffering. Validation still preserves source lines for normal diagnostics.

func (*Validator) ValidateReaderWithOptions added in v0.5.0

func (v *Validator) ValidateReaderWithOptions(
	reader io.Reader,
	opts ValidationContext,
) (*ValidationResult, error)

ValidateReaderWithOptions is the reader-based form of ValidateWithOptions.

func (*Validator) ValidateWithOptions

func (v *Validator) ValidateWithOptions(data []byte, opts ValidationContext) *ValidationResult

ValidateWithOptions validates YAML data with custom options.

type ValueValidator

type ValueValidator interface {
	Validate(node *yaml.Node, path string, ctx *ValidationContext)
}

ValueValidator validates a node's value. Validator instances may be reused concurrently; custom implementations that keep mutable state must therefore provide their own synchronization.

type ValueValidatorCloner added in v0.4.0

type ValueValidatorCloner interface {
	CloneValueValidator() ValueValidator
}

ValueValidatorCloner can be implemented by stateful/configurable custom validators so CompileFieldSchema can snapshot their configuration.

Directories

Path Synopsis
cmd
yamlvalidator command
examples
advanced command
basic command
Example demonstrates how to use the yamlvalidator package to validate Kubernetes-like manifests with comprehensive schema definitions.
Example demonstrates how to use the yamlvalidator package to validate Kubernetes-like manifests with comprehensive schema definitions.
internal
thirdparty/xnet/idna
Package idna implements IDNA2008 using the compatibility processing defined by UTS (Unicode Technical Standard) #46, which defines a standard to deal with the transition from IDNA2003.
Package idna implements IDNA2008 using the compatibility processing defined by UTS (Unicode Technical Standard) #46, which defines a standard to deal with the transition from IDNA2003.
thirdparty/xtext/secure/bidirule
Package bidirule implements the Bidi Rule defined by RFC 5893.
Package bidirule implements the Bidi Rule defined by RFC 5893.
thirdparty/xtext/transform
Package transform provides reader and writer wrappers that transform the bytes passing through as well as various transformations.
Package transform provides reader and writer wrappers that transform the bytes passing through as well as various transformations.
thirdparty/xtext/unicode/bidi
Package bidi contains functionality for bidirectional text support.
Package bidi contains functionality for bidirectional text support.
thirdparty/xtext/unicode/norm
Package norm contains types and functions for normalizing Unicode strings.
Package norm contains types and functions for normalizing Unicode strings.
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL