> IronFlow documentation for v1.20.0. [HTML version](https://ironflow.work/docs/nodes/validate_schema) · [Release source](https://github.com/skitsanos/ironflow/blob/v1.20.0/docs/nodes/validate_schema.md)

# `validate_schema`

Validate context data against a JSON Schema.

## Parameters

| Parameter    | Type   | Required | Default | Description                                              |
|--------------|--------|----------|---------|----------------------------------------------------------|
| `source_key` | string | Yes      | --      | Top-level context key whose value will be validated      |
| `schema`     | object/boolean | No* | -- | A JSON Schema to validate the data against |
| `schema_key` | string | No* | -- | Context key containing a decoded JSON Schema or JSON Schema string |

*Provide exactly one of `schema` or `schema_key`.

The node retrieves the value stored under `source_key` in the workflow context and validates it using the provided JSON Schema. If validation fails, the node returns an error and the workflow step is marked as failed.

Use this node when the value is already in your context as JSON (object/array/value).  
If the context value is a raw JSON string, use [`json_validate`](/docs/nodes/json_validate) instead.

## Schema References

Validation is offline-only. References bundled in the supplied schema work;
references requiring network or file retrieval fail normally without fetching.
See [JSON Schema validation](https://github.com/skitsanos/ironflow/blob/v1.20.0/docs/JSON_SCHEMA_VALIDATION.md) for bundled-reference
examples, error behavior, and cancellation boundaries.

## Context Output

- `validation_success` -- boolean indicating whether validation passed
- `validation_errors` -- array of error description strings (empty on success)

**Note:** When validation fails the node returns a structured error. Downstream
steps execute only if a dedicated `on_error` handler successfully resolves that
failure. After retries are exhausted, the final validation result is buffered
for the source phase barrier and the handler receives its source-exact copy in
`_error_output`. Normal shared keys still follow declaration-order collision
precedence if a parallel step publishes the same names.

## Example

```lua
local flow = Flow.new("user_registration")

flow:step("validate", nodes.validate_schema({
    source_key = "payload",
    schema = {
        type = "object",
        required = { "email", "name" },
        properties = {
            email = { type = "string" },
            name  = { type = "string" },
            age   = { type = "integer", minimum = 0 }
        }
    }
}))

flow:step("done", nodes.log({
    message = "Validation passed for ${ctx.payload.name} (${ctx.payload.email})"
})):depends_on("validate")

return flow
```

### Validate with a schema loaded from context

```lua
local flow = Flow.new("validate_from_context")

flow:step("read_schema", nodes.read_file({
    path = "schemas/user.schema.json",
    output_key = "schema"
}))

flow:step("validate", nodes.validate_schema({
    source_key = "payload",
    schema_key = "schema_content"
})):depends_on("read_schema")

return flow
```
