# Conditions (/docs/guides/conditions)

Compare fields with values, combine conditions and handle unknown values.



A condition decides whether an item is reported. It is a **comparison**, or a **combination** of conditions.

## Comparisons [#comparisons]

A comparison names a [field](/docs/reference/fields), an [operator](/docs/reference/operators) and, for most operators, a value:

```json
{ "field": "clip.scale", "operator": "greaterThan", "value": 120 }
```

The value is a literal (a number, a string or a boolean), or a reference to another field, including an option:

```json
{ "field": "clip.scale", "operator": "greaterThan", "value": { "field": "options.max" } }
```

```json
{ "field": "clip.end", "operator": "lessThanOrEqual", "value": { "field": "sequence.inPoint" } }
```

Types must match: `greaterThan` on a string field, or a string value for a number field, is rejected when the rule loads.

Some operators take a particular value:

```json
{ "field": "clip.scale", "operator": "between", "value": [50, 150] }
```

```json
{ "field": "clip.source.extension", "operator": "in", "value": ["mov", "mxf"] }
```

```json
{ "field": "marker.name", "operator": "matches", "value": "^Chapter \\d+$" }
```

```json
{ "field": "clip.source.mediaPath", "operator": "exists" }
```

`between` includes its bounds. `matches` takes a JavaScript regular expression, written as a JSON string (so `\d` is `"\\d"`), and matches anywhere unless anchored with `^` and `$`. `exists` takes no value. All operators are listed in [Operators](/docs/reference/operators).

JSON has no infinity: write `"Infinity"` or `"-Infinity"` where a number is expected. A silenced audio clip is `{ "field": "clip.volume", "operator": "equals", "value": "-Infinity" }`.

## Combinations [#combinations]

```json
{ "all": [ /* conditions */ ] }
{ "any": [ /* conditions */ ] }
{ "not": /* condition */ }
```

* `all` holds when every condition in it holds (and).
* `any` holds when at least one does (or).
* `not` inverts one condition.

They nest freely. Each combination object holds exactly one of these keys.

```json title="An enabled video clip scaled outside 50–150 %"
{
  "all": [
    { "field": "clip.trackType", "operator": "equals", "value": "video" },
    { "field": "clip.disabled", "operator": "equals", "value": false },
    {
      "any": [
        { "field": "clip.scale", "operator": "lessThan", "value": 50 },
        { "field": "clip.scale", "operator": "greaterThan", "value": 150 }
      ]
    }
  ]
}
```

## Unknown values [#unknown-values]

Some fields can be **unknown**: their type ends in `?` in the [fields reference](/docs/reference/fields). An audio clip has no scale; a clip without source media has no media path.

Every comparison is **false** when its field, or a field it refers to, is unknown, except `exists` and `notExists`. So `clip.scale lessThan 50` does not report audio clips, and neither does `clip.scale notEquals 100`.

<Callout type="warn" title="The trap: not">
  `not` turns a false comparison into true. `{ "not": { "field": "clip.scale", "operator": "equals", "value": 100 } }` **does** match every audio clip, since their scale is unknown.
</Callout>

When a rule needs a known value, say so:

* prefer positive comparisons, `lessThan min` or `greaterThan max`, over `not between`;
* or add `{ "field": "clip.scale", "operator": "exists" }` to an `all`.

## Conditions shared by every check [#conditions-shared-by-every-check]

There is no rule-wide filter. When a rule has [several checks](/docs/guides/checks) and each needs the same conditions (an enabled clip, a known value), repeat them in each check.
