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

# GLua Diagnostic Rules Reference

> Complete reference for every diagnostic rule in GLua, including what each rule catches and how to configure its severity level.

GLua ships with built-in diagnostics that catch common mistakes in Garry's Mod Lua. This page lists every rule, grouped by the area it covers.

Each rule has two names, and they are not the same thing:

* a **diagnostic code** such as `net-payload-mismatch`, shown in the Problems panel and used by [inline suppressions](/glua/configuration/suppressions)
* a **settings key** such as `netReadWriteMismatch`, used in `.glua.json` and in VS Code settings

Severity accepts `error`, `warning`, `information`, `hint` or `off`.

Every rule has its own section below, and the code shown in the Problems panel
links straight to it. `glua rules` lists the same catalogue in the terminal, and
SARIF output carries the same links into GitHub code scanning.

## Globals

### `undefined-global`

`undefinedGlobal` · default `warning`

A global that is neither a known GMod API member nor assigned anywhere in the
workspace — usually a typo, sometimes a dependency this project does not declare.

Existence checks are respected, so the usual way of depending on an optional
addon does not trigger it:

```lua theme={"system"}
if DarkRP and DarkRP.getPhrase then
  print(DarkRP.getPhrase("hello"))
end
```

For a hard dependency, declare it under [`globals`](/glua/configuration/config-files)
rather than turning the rule off — that keeps the check working for real typos.

### `global-write`

`globalWrite` · default `off`

Writing to a global instead of declaring a local, which leaks the name into `_G`
where any other addon can collide with it. Noisy by design in code that uses a
single global table on purpose, so it ships off.

### `unused-local`

`unusedLocal` · default `hint`

A local declared but never read. Names starting with `_` are exempt, which is
the conventional way to say a value is deliberately ignored.

## Realms

### `realm-violation`

`realmViolation` · default `warning`

A call to API that cannot exist in this file's realm — a serverside-only
function in a clientside file, or the reverse. The call is `nil` at runtime, so
this is an error waiting to happen rather than a style question.

Reported as `information` instead when the realm was inferred from a `cl_`/`sv_`
filename prefix, since that is a convention rather than a guarantee: plenty of
addons include a `cl_` file on both realms. A directory such as `lua/autorun/server/`
is treated as certain.

## Net messages

### `net-unregistered`

`netMessage` · default `warning`

`net.Start` on a message never passed to `util.AddNetworkString`. Fails at
runtime. A quick fix inserts the registration.

### `net-never-dispatched`

`netMessage` · default `warning`

A `net.Start` block that never calls `net.Send`, `net.Broadcast` or
`net.SendToServer`, so the message is built and dropped. Silent at runtime,
which is what makes it worth reporting.

### `net-never-received`

`netMessage` · default `warning`

A message that is sent but has no `net.Receive` anywhere in the workspace.

### `net-never-sent`

`netMessage` · default `warning`

A `net.Receive` for a message nothing ever sends — usually a rename that
happened on one side only.

### `net-payload-mismatch`

`netReadWriteMismatch` · default `warning`

The `net.Write*` sequence in the sender does not match the `net.Read*` sequence
in the handler. Reading a string where an integer was written does not error; it
returns nonsense.

## Hooks and timers

### `unknown-hook`

`unknownHook` · default `information`

A hook name that is neither documented nor fired anywhere in the workspace.
Quick fixes offer the closest known names by edit distance.

### `duplicate-hook-identifier`

`duplicateIdentifier` · default `warning`

Two `hook.Add` calls with the same event and identifier in overlapping realms.
The second silently replaces the first, so one of the two never runs.

### `duplicate-timer-name`

`duplicateIdentifier` · default `warning`

Two `timer.Create` calls with the same name in overlapping realms, with the same
consequence: the second replaces the first.

## API calls

### `deprecated`

`deprecated` · default `warning`

Use of API the wiki marks deprecated or removed. The message includes the
documented replacement.

### `argument-count`

`argumentCount` · default `warning`

The wrong number of arguments, checked against every documented call form.
Skipped for the Lua standard library, whose documented signatures are not
precise enough to check against — `table.insert` is documented only in its
three-argument form, and the two-argument form is everywhere in real code.

### `argument-type`

`argumentType` · default `warning`

An argument whose inferred type cannot match the documented parameter. Only
fires when no documented overload accepts what was passed.

## Performance

### `perf-hot-path`

`perfHotPath` · default `warning`

Expensive work reached from something the engine runs every frame or tick — a
render hook, `ENT:Think`, a `timer.Create` that repeats forever at 0.5s or less.
The message names the chain of functions that reaches it, so a finding four
calls and two files away from its hook still explains itself.

Calls behind a `CurTime()` guard, a `nextThink`-style field, or a one-time
`if not x then` gate are skipped, since those already rate-limit themselves.
[Full description](/glua/features/hot-paths).

## Dead code

### `unused-function`

`unusedFunction` · default `off`

A function this workspace defines and never calls, references or registers.
Methods defined with a colon, scripted class hooks and anything extending an API
library are exempt, since those are reached through a value rather than a name.

**Off by default**: an addon meant to be used by other addons is full of these
on purpose. `glua doctor` lists them either way.

## Files

### `missing-addcsluafile`

`missingAddCSLuaFile` · default `warning`

A clientside file that is `include`d but never sent with `AddCSLuaFile`, so
clients never receive it. Directories the engine networks itself are skipped. A
quick fix inserts the missing call.

### `missing-asset`

`missingAsset` · default `off`

A material, model or sound path that does not exist. Missing content never
raises a Lua error — it renders as the checkerboard, the error model, or
silence — which is exactly why a typo here can survive a long time.

Requires [`workspace.gamePath`](/glua/configuration/config-files), and **off by
default on purpose**: content mounted from the Workshop or a separate content
pack is invisible from here, so on a typical server most findings would be
wrong. Turn it on only if every asset you reference ships in this repository.

## Suppressions

### `unused-suppression`

`unusedSuppression` · default `hint`

A `-- glua-ignore` or `-- glua-disable` comment that never silenced anything.

A suppression outlives the finding it was written for: the code gets fixed, the
comment stays, and from then on it silently covers whatever appears on that line
next. A misspelled rule name looks exactly like working protection, and so does
one for a rule that has since been turned off.

Only reported for files that parse. A parse error stops most rules from running,
so every directive in the file would read as dead.

```lua theme={"system"}
-- glua-ignore unused-local
local count = 1
print(count)
```

The local is read, so nothing is being suppressed and the comment is dead — it
outlived the finding it was written for. A misspelled rule name produces the
same report, which is the point: `unusedLocal` where `unused-local` belonged
silences nothing and looks like it does.

## Syntax

Always reported as errors, and not configurable.

### `syntax`

The file does not parse. Formatting is disabled for the file while this is
present, since reformatting a file the parser could not read would lose code.

### `compound-assignment`

`x += 1` is not valid Lua, however much it looks like it should be. A quick fix
rewrites it as `x = x + 1`.

## Setting severity

Tune rules in `.glua.json` using the **settings key** given under each rule
above. Each accepts `error`, `warning`, `information`, `hint` or `off`.

```json theme={"system"}
{
  "diagnostics": {
    "undefinedGlobal": "error",
    "unusedLocal": "off",
    "realmViolation": "error",
    "netMessage": "warning",
    "netReadWriteMismatch": "error",
    "unknownHook": "warning",
    "duplicateIdentifier": "error",
    "deprecated": "warning",
    "argumentCount": "warning",
    "argumentType": "warning",
    "missingAddCSLuaFile": "warning",
    "globalWrite": "off",
    "perfHotPath": "warning",
    "unusedFunction": "off",
    "missingAsset": "off",
    "unusedSuppression": "hint"
  }
}
```

<Info>
  Omitted rules keep their built-in default, so you only list what you want to change. The [hosted JSON schema](/glua/reference/glua-schema) validates these keys as you type — an unknown key is flagged in the editor.
</Info>

<Warning>
  Do not use the diagnostic code as a settings key. `"net-payload-mismatch": "error"` is not a valid entry; the key is `netReadWriteMismatch`. Codes are for the Problems panel and for `-- glua-ignore`.
</Warning>
