NEXSS FLOW · INTEGRATIONS
6 min read | Updated 2026-10-01
Integrations

Runtime Request Validation

How @config:strict and :strict / :lenient close the validation gap that projections and @{} injections open — via validation.Struct on typed actions.

validationstrictlenienttagsxerr

The problem

-> is a data pipe, not a type pipe. When A returns {name: "x"} and B expects struct{Description string; Tier string}, Coerce silently zeroes the mismatched fields.

nflow nflow
A: {name: "x", tier: "pro"}
         ↓ InvokeAny → Coerce[Req_B]
B: {Description: "", Tier: "pro"}   ← name vanished, no error

The compile-time edge check in flow/pipeline_types.go catches only direct A -> B. Any projection { } or with @{ } in between disables the check, because the parser cannot see what flows through. Runtime strict closes that gap.

Four validation states

The interaction between @config:strict, :strict, and :lenient determines whether validation runs.

  • No @config:strict, no :strict, no :lenient → validation does **not** run.
  • @config:strict=true alone → validation runs.
  • :strict alone on an atom → validation runs for that atom.
  • @config:strict=true + :lenient on an atom → validation does **not** run for that atom.
  • @config:strict=true + :strict + :lenient on the same atom → :lenient wins; validation does not run.
Typed actions only
When TypedPayload.ReqPayload() returns an any action, validation never runs, regardless of flags. There is no schema to check.

Three ways to enable

nflow nflow
# Per file
@config:strict=true
producer -> { name: .name } -> consumer

# Per atom
producer -> { name: .name } -> consumer:strict

# Opt-out per atom (when global strict is on)
@config:strict=true
producer -> { internal_thing: .x } -> helper:lenient

Example with validate tags

Action with validate tags + strict mode = runtime validation that produces xerr.KindValidation (HTTP 400) on failure.

go go
type CreateUserReq struct {
    Name  string `json:"name"  validate:"required,min=3"`
    Email string `json:"email" validate:"required,email"`
}
nflow nflow
@config:strict=true

# passes
{ name: "Ada", email: "ada@nexss.dev" } -> create_user

# runtime: [Validation] validation failed
#    field "name": failed 'min' check (expected 3)
{ name: "Al", email: "ada@nexss.dev" } -> create_user

# runtime: "email" field missing
{ name: "Ada" } -> create_user
What strict does not do
It does not validate the response (only request). It does not run on any actions. It does not check at compile time. It does not block @{} injection (args join validation). It does not check @schema (separate runtime guard for map[string]any).