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

# Static analysis

> Reference for every check GoRules runs against your graphs and policies - and how to fix what it finds.

GoRules continuously analyses every graph and policy as you edit - no run required. Findings appear in the document's **Problems** tab, on the [Quality Control](/brms/quality/quality-control) page, and as a [pre-flight check](/brms/review/review) when you save.

<Frame caption="The Problems tab with two findings and suggested fixes">
  <img src="https://mintcdn.com/gorules/mAGHMyeoymmduVBY/images/brms/graph-problems.png?fit=max&auto=format&n=mAGHMyeoymmduVBY&q=85&s=2df0bdf05a26e5f8f0bc4d87677130cd" alt="Problems tab showing PREFER_DICTIONARY hints on decision table output columns, with explanations and suggested fixes" width="1600" height="1000" data-path="images/brms/graph-problems.png" />
</Frame>

Each finding has a severity:

| Severity | Meaning                                                                                         |
| -------- | ----------------------------------------------------------------------------------------------- |
| Error    | The document will misbehave or fail to evaluate. Fix before shipping.                           |
| Warning  | Likely a mistake, but evaluation still works.                                                   |
| Hint     | A quality suggestion. Hints appear in the Problems tab (toggleable) but not on Quality Control. |

<Info>
  Static analysis needs to know your types. A graph whose input node has no schema - or an empty one - reports `MISSING_INPUT_SCHEMA` and skips deeper checks until you define one in the [Interface tab](/brms/build/graphs#interface).
</Info>

## Names and types

| Code                       | What it means                                                                                                                                                |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `UNDEFINED_VARIABLE`       | An expression references a property that nothing declares or computes. Usually a typo or a missing data model property.                                      |
| `TYPE_MISMATCH`            | A value doesn't match the expected type - often an optional value used in arithmetic without a fallback, or a typed table cell with the wrong kind of value. |
| `INVALID_EXPRESSION`       | The expression doesn't evaluate against the resolved types.                                                                                                  |
| `PARSE_ERROR`              | The expression isn't valid ZEN syntax.                                                                                                                       |
| `IMPLICIT_ANY`             | A schema leaf has no type, so it resolves to `any` and can't be checked. Give it a concrete type.                                                            |
| `INVALID_NAME`             | An identifier contains dots, brackets, or whitespace, or starts with a digit.                                                                                |
| `UNRESOLVED_FUNCTION_TYPE` | A function's return type can't be determined.                                                                                                                |
| `MAX_DEPTH_EXCEEDED`       | Nesting exceeds the analyser's depth limit.                                                                                                                  |

## Writes and dependencies

| Code                      | What it means                                                                                                           |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `DUPLICATE_WRITER`        | Two blocks write the same property. Checked across a policy's whole import group - the conflict can be in another file. |
| `CYCLIC_DEPENDENCY`       | Rules depend on each other in a loop, so no valid order exists.                                                         |
| `SELF_REFERENCING_WRITE`  | A block writes a property it also reads.                                                                                |
| `INPUT_OVERRIDE`          | A rule overwrites a property declared as input.                                                                         |
| `INVALID_WRITE_PATH`      | The write target isn't a valid property path.                                                                           |
| `PARTIAL_OBJECT_WRITE`    | A block writes part of an object another block writes whole.                                                            |
| `MIXED_SCOPE`             | One block writes multiple entities, or mixes entity and global writes. Split it.                                        |
| `UNREACHABLE_ENTITY_READ` | A block reads an entity no execution path can populate.                                                                 |

## Data models, dictionaries, and imports

| Code                        | What it means                                                                                               |
| --------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `DATA_MODEL_COLLISION`      | The same entity is declared twice with different shapes, or an entity, global, and dictionary share a name. |
| `UNKNOWN_DATA_MODEL_TARGET` | A reference points at a name that is neither an entity nor a dictionary.                                    |
| `DUPLICATE_PROPERTY`        | A data model declares the same property twice.                                                              |
| `DUPLICATE_ENUM_VALUE`      | A dictionary contains the same value twice.                                                                 |
| `IMPORT_NOT_FOUND`          | An imported policy path doesn't resolve to a document.                                                      |
| `CIRCULAR_IMPORT`           | Policies import each other in a cycle.                                                                      |

## Structure and completeness

| Code                           | What it means                                                                                        |
| ------------------------------ | ---------------------------------------------------------------------------------------------------- |
| `EMPTY_BLOCK`                  | A block has no content. An error on assertions; a warning on empty tables, matches, and expressions. |
| `MISSING_DEFAULT_BRANCH`       | A match has no branch for the remaining cases.                                                       |
| `UNSUPPORTED_NESTED_ITERATION` | Iteration nested deeper than the engine supports.                                                    |
| `INVALID_GRAPH_STRUCTURE`      | The graph's nodes and edges don't form a valid flow.                                                 |
| `UNREACHABLE_NODE`             | A node no path from the input can reach.                                                             |
| `MISSING_INPUT_SCHEMA`         | The graph's input node has no usable schema; deeper checks are skipped.                              |
| `UNCHECKED_NODE`               | A node the analyser couldn't verify.                                                                 |
| `NULLABILITY_DIVERGENCE`       | A value's nullability differs between paths that later join.                                         |

## Quality hints

Hints don't indicate bugs - they point at rules that could be simpler, safer, or easier to maintain.

| Code                        | Suggestion                                                                                                                                              |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `REDUNDANT_NULLISH`         | A `??` fallback on a value that is never null - dead code; remove the fallback.                                                                         |
| `REPEATED_DERIVATION`       | The same sub-expression is computed in several places. Compute it once and reference it.                                                                |
| `PREFER_MATCH`              | A construct that would read better as a match block.                                                                                                    |
| `PREFER_DICTIONARY`         | An inline set of fixed values that should be a named [dictionary](/brms/build/policies#dictionaries) - you get membership checking and labels for free. |
| `REDUNDANT_TABLE_ROW`       | A decision table row that can never produce a distinct outcome.                                                                                         |
| `NON_DISCRIMINATING_COLUMN` | A table column that never affects which row matches.                                                                                                    |
| `REDUNDANT_PARENTHESES`     | Parentheses that don't change evaluation.                                                                                                               |
