> ## Documentation Index
> Fetch the complete documentation index at: https://docs.substrate.42.pe/llms.txt
> Use this file to discover all available pages before exploring further.

# substrate validate — Lint Boards, Members, and Policies

> substrate validate lints your boards, members, and policies without starting a server. Exits non-zero on errors; advisory warnings exit 0. CI-safe.

Run `substrate validate` to lint your boards, members, and policies without starting a server or touching the database. Errors exit non-zero with a message naming the file and how to fix it. Warnings are advisory and exit `0`. The command is designed to be dropped directly into a CI pipeline.

## Usage

```shell theme={null}
substrate validate
```

## What It Catches

### Errors — exit non-zero

These are anything that would cause a load to fail:

* Malformed JSON
* A board that doesn't match the schema
* A policy definition that doesn't parse against its type
* A `from_group` or `to_group` that resolves to no group
* An enum field with no values
* Duplicate ids

The error message names the file and describes how to fix it.

### Warnings — advisory, exit 0

* A guard whose `from_group` equals its `to_group` (can never fire on a real move)
* A `team[].member` with no registry file
* A binding `groups` id that is not a group on the board
* A duplicate member id, or a malformed member file (warned and skipped)

## Using in CI

```yaml theme={null}
- run: substrate validate
```

A corrupt substrate fails the build. Advisory warnings do not.

<Warning>
  This is a **structural** lint, not a behavioural one. It cannot tell you that a guard names the wrong group or that a field path resolves to nothing — the definition is well-formed either way. Pair it with a live probe too: see [Validate Gates](/authoring/validate-gates).
</Warning>
