# validate

Validate artifacts against schemas

Canonical URL: https://docs.paradoc.dev/cli/commands/validate/

Validates one or more Paradoc artifacts against the core schema.

## Usage

```bash
paradoc validate <artifacts...> [options]
```

## Arguments

| Argument    | Description                                              |
| ----------- | -------------------------------------------------------- |
| `artifacts` | One or more artifact files (JSON/YAML), or `-` for stdin |

## Options

| Option                 | Description                                                             |
| ---------------------- | ----------------------------------------------------------------------- |
| `--json`               | Output machine-readable JSON result                                     |
| `--silent`             | Suppress console output (exit code only)                                |
| `--expect-kind <kind>` | Assert artifact kind: `form`, `document`, `checklist`, `bundle`         |
| `--schema-only`        | Only validate artifact schema (skip layer and content reference checks) |
| `--layers-only`        | Validate the schema and referenced files (paths + checksums)            |
| `--checksum-only`      | Validate the schema and verify checksums for files that exist           |

The scope flags (`--schema-only`, `--layers-only`, `--checksum-only`) are mutually exclusive. Every scope first requires a schema-valid artifact.

## Description

The `validate` command takes one or more artifact files. Each one is parsed and run through up to three validation phases, and its own result is reported, in argument order. First, each file's `$schema` must name the current [schema version](/schemas#loading-rules); a file written for another version fails and names [`paradoc migrate`](/cli/commands/migrate), as every command that reads an artifact file does.

1. **Schema** — checks the artifact structure against the Paradoc schema, its logic expressions, the template expressions of inline layers, that each PDF binding value is a known Paradoc path, and what the layers refer to (see [Layer references](#layer-references))
2. **Layers** — for file-backed layers, checks file existence and verifies checksums, checks the template expressions of text and DOCX layers and that each text layer places its `'flow'` signature slots, checks that each PDF binding key is an AcroForm field of the template, and checks that bound values can fill a form's PDF text fields
3. **Content references** — for file-backed `instructions` and `agentInstructions`, checks file existence and verifies checksums

A layer file or content reference file that does not exist is an error.

Content reference validation runs automatically for any artifact kind that has `instructions` or `agentInstructions` set with `kind: "file"`. It is skipped by `--schema-only` and when reading from stdin (no file context).

A template error names the layer, the line and column (or, in a DOCX layer, the paragraph), the expression, and the problem, including the replacement for syntax templates no longer accept.

A form's PDF layer `bindings` map AcroForm field names (keys) to Paradoc paths (values). A value that names no field, party, computed value, or annex of the form is an error naming the layer and the key; when the key is a field of the form, the error says the binding is inverted. A key that is not an AcroForm field in the template is an error that lists the template's fields.

For a form's PDF layer, each binding to a text field is checked at the bound field's length limit. A typical value of that length that cannot fit the box at 6 points, an option value that cannot fit, or more characters than a comb field has boxes is an error naming the layer, the PDF field, the artifact path, and the limit. When only the widest value (all `W`) overflows, or a bound text field has no `maxLength` or `pattern`, it is a warning. See [Checking bindings before filling](/sdk/renderers/pdf#checking-bindings-before-filling).

### Layer references

Each of these is an error that names the layer, slot, or role at fault. Render or seal would fail on each one:

* a `defaultLayer` that names no layer
* a signature slot for a party role the artifact does not declare
* a `'flow'` slot on a PDF or DOCX layer, or a `'flow'` slot whose type is not `signature` or `initials`
* a party whose signature is required but has no slot on a layer that declares `signatures`
* a `'flow'` slot that no `signature(...)` or `initials(...)` directive in the layer's template places. A directive whose location is computed counts for every slot of its type. React layers are not checked, since their template is code. The check assumes core's text renderer; a seal renderer you register for a text MIME type receives the markers itself.

Problems that depend on how you seal, such as a missing converter or a renderer override, are reported by `seal()`.

The command exits with code `0` only if every file is valid (warnings are allowed); it exits `1` if any file has errors, including a file that cannot be read or parsed. A file that fails to read does not stop the remaining files from being validated.

## Examples

Validate an artifact:

```bash
paradoc validate my-form.yaml
```

Validate several artifacts in one run:

```bash
paradoc validate my-form.yaml my-document.yaml
```

Validate from stdin:

```bash
cat my-form.yaml | paradoc validate -
```

Assert expected kind:

```bash
paradoc validate my-form.yaml --expect-kind form
```

Schema only (skip file checks):

```bash
paradoc validate my-form.yaml --schema-only
```

Get JSON output:

```bash
paradoc validate my-form.yaml --json
```

Silent mode (for scripts):

```bash
paradoc validate my-form.yaml --silent && echo "Valid"
```

## Output

When valid:

```
✓ Schema
  Kind:    form
  Name:    lease-agreement
  Version: 1.0.0
  Source:  lease-agreement.yaml

Layers:
  ✓ pdf [file, application/pdf]
      path: ./lease-template.pdf
      file:     found
      checksum: verified

Content References:
  ⚠ instructions [file, text/markdown]
      path: ./instructions.md
      file:     found
      checksum: not set

✓ Valid (1 warning)
```

When invalid:

```
✗ Schema validation failed:
  ✗ fields.rent: Expected type "object" but received "string"
  ✗ version: Required field missing

✗ Validation failed
```

## JSON output

With a single artifact, `--json` prints one result object. With more than one artifact, it prints a JSON array of result objects, in argument order; a file that fails to read reports `{ "ok": false, "source": "...", "error": "..." }`.

The result object includes `layers` and `contentRefs` arrays when present:

```json
{
  "ok": true,
  "source": "my-form.yaml",
  "artifact": {
    "name": "lease-agreement",
    "kind": "form",
    "version": "1.0.0"
  },
  "errors": [],
  "warnings": [
    {
      "message": "No checksum set. Run `paradoc fix` to add one.",
      "path": ["instructions", "checksum"]
    }
  ],
  "layers": [
    {
      "key": "pdf",
      "kind": "file",
      "mimeType": "application/pdf",
      "path": "./lease-template.pdf",
      "fileExists": true,
      "checksumMatch": true,
      "ok": true
    }
  ],
  "contentRefs": [
    {
      "field": "instructions",
      "kind": "file",
      "mimeType": "text/markdown",
      "path": "./instructions.md",
      "fileExists": true,
      "ok": true
    }
  ]
}
```

## See also

* [fix](/cli/commands/fix) - Auto-fix common issues
* [new](/cli/commands/new) - Create new artifacts

An artifact argument may be a file path or an installed `@namespace/name` reference from `.paradoc/lock.json`. An uninstalled reference fails with an error.
