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

# Exit codes

> geval check and geval demo exit codes — PASS, REQUIRE_APPROVAL, BLOCK — for CI and scripts.

## Successful evaluation (`geval check`, `geval demo`)

These commands exit with:

| Code    | Outcome               | Typical CI use                                      |
| ------- | --------------------- | --------------------------------------------------- |
| **`0`** | **PASS**              | Allow merge / deploy                                |
| **`1`** | **REQUIRE\_APPROVAL** | Stop for human review (or your org’s override flow) |
| **`2`** | **BLOCK**             | Fail the job; do not merge                          |

This ordering is intentional: many systems treat **non-zero** as “needs attention,” while **`1`** vs **`2`** lets you distinguish **approval** from **hard block** if you script it.

For **GitHub Actions** patterns (labels, follow-up jobs, Slack, `geval approve`), see **Handling REQUIRE\_APPROVAL: extra logic** on the [GitHub Actions](/integration/github-actions) page.

## Configuration and parse errors

If the contract cannot be loaded, policies are missing, or signals JSON is invalid, the process exits **non-zero** with an error message on stderr — treat as **pipeline misconfiguration**, not as a policy BLOCK.

Always run **`geval validate-contract`** in a separate CI step if you want fast feedback without signals.

## Example shell handling

```bash theme={null}
./geval check -c contract.yaml --signals signals.json
code=$?
case $code in
  0) echo "PASS" ;;
  1) echo "REQUIRE_APPROVAL" ;;
  2) echo "BLOCK" ;;
  *) echo "Error or unexpected exit: $code" ;;
esac
exit $code
```

## JSON output

`geval check --json` prints structured decision data to stdout; **exit codes still apply** the same way.

## See also

[check](/cli/check) · [GitHub Actions](/integration/github-actions)
