Validation as a Special Case

By now, we have used Tagex to normalize data, select behavior based on capability, and define explicit success boundaries.

In this guide, we look at validation — not as the primary goal of Tagex, but as a specific configuration of its execution model.

What Validation Really Is

Validation answers a narrow question:

Can this value be accepted as-is?

In Tagex terms, validation means:

  • The directive evaluates a value
  • The value is not mutated
  • Failure is expressed as an error
  • No side effects occur

This maps directly to EvalMode.

A Validation Directive

Let’s define a simple range check.


type RangeDirective struct {
    Min int `param:"min"`
    Max int `param:"max"`
}

func (d *RangeDirective) Name() string {
    return "range"
}

func (d *RangeDirective) Mode() tagex.DirectiveMode {
    return tagex.EvalMode
}

func (d *RangeDirective) Handle(val int) (int, error) {
    if val < d.Min || val > d.Max {
        return val, fmt.Errorf(
            "value %d out of range [%d, %d]",
            val, d.Min, d.Max,
        )
    }
    return val, nil
}

This directive evaluates the field and leaves it unchanged. Its only observable effect is success or failure.

Using Validation Declaratively


type Registration struct {
    Age int `check:"range, min=18, max=130"`
}

This looks like a traditional validation use case — and it is.

The difference lies in what happens next.

Validation Inside a Success Boundary

Validation becomes significantly more powerful when combined with PostProcessing.


type Registration struct {
    Age int `check:"range, min=18, max=130"`

    repo *Repository
}

func (r *Registration) Success() error {
    return r.repo.CreateUser(r.Age)
}

If Success() runs, validation has already succeeded.

There is no need to:

  • Check return values
  • Track validation state
  • Duplicate error handling

Why Validation Does Not Define Tagex

Validation libraries typically:

  • Focus exclusively on rejecting input
  • Accumulate error messages
  • Have no notion of success beyond “no errors”

Tagex, by contrast:

  • Executes arbitrary semantics
  • Supports mutation and adaptation
  • Defines an explicit success path

Validation fits naturally into this model, but it does not drive it.

When Validation Is the Right Tool

Validation works well when:

  • You want to reject invalid input early
  • Fields must remain unchanged
  • Failure has no side effects

Tagex supports this cleanly — without committing you to validation-only thinking.

The Unifying Idea

Normalization, capability selection, validation, and post-processing all use the same mechanism:

  • Tags select directives
  • Directives define semantics
  • The execution model enforces guarantees

Validation is simply one point in this design space.

Next Guide

In the next guide, we will look at custom converters and semantic parsing, and how overriding defaults lets you adapt Tagex to domain-specific meaning.