---
product: "AG Grid"
title: "Development Validation"
description: "Catch AG Grid misconfiguration early with development-time validation diagnostics."
framework: javascript
version: "36.2.0"
related:
    - title: "Installation"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/installation/"
    - title: "Registering Modules"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/modules/"
    - title: "Installing Enterprise Licence"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/license-install/"
    - title: "Migration"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/migration/"
    - title: "Codemods"
      url: "https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/codemods/"
llms: "https://www.ag-grid.com/archive/36.2.0/llms.txt"
---

# Development Validation

AG Grid can validate your configuration during development and report problems that are otherwise easy to miss in the console. Enable these diagnostics in development builds only — they are not part of the `AllCommunityModule` / `AllEnterpriseModule` bundles, so production stays small.

## Enabling Validation

Call `enableDevValidations` once, before any grid is created:

```js
import { enableDevValidations } from 'ag-grid-community';

if (process.env.NODE_ENV !== 'production') {
    enableDevValidations();
}
```

This is equivalent to registering the module directly with `ModuleRegistry.registerModules([ValidationModule])`.

Without the module, console messages are reduced to an error code and a documentation link rather than the full text.

## Options

Pass options to `enableDevValidations` to configure:

```js
import { enableDevValidations } from 'ag-grid-community';

enableDevValidations({
    showOverlayOn: ['deprecation', 'warning', 'error'],
    throwOn: ['warning', 'error'],
    suppress: [],
});
```

If you register the module explicitly (instead of using `enableDevValidations`), then pass the same options via `ValidationModule.with({ showOverlayOn: ['deprecation', 'warning', 'error'], throwOn: ['warning', 'error'], suppress: [] })`

Configuration is global and applies to every grid on the page, with the options from the last call being used.

### Overlay

The overlay lists the diagnostics captured for a grid on top of that grid, with controls to copy them or dismiss the overlay. It is shown by default.

Diagnostics have one of three severities:

- `'deprecation'` — use of a deprecated option or feature
- `'warning'` — a likely misconfiguration the grid can recover from
- `'error'` — an invalid configuration

Set `showOverlayOn` to an array of the severities to show. For example, to show warnings and errors but not deprecations:

```js
enableDevValidations({ showOverlayOn: ['warning', 'error'] });
```

Defaults to `['deprecation', 'warning', 'error']` (every severity). Pass `[]` to hide the overlay.

In the example below, a column definition includes a property the grid does not recognise, so the resulting warnings surface in the overlay:

#### Overlay

```ts
import {
  AllCommunityModule,
  ColDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";

// Enable development validations so captured diagnostics surface in an overlay over the grid.
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([AllCommunityModule]);

const gridOptions: GridOptions = {
  columnDefs: [
    // A stray property the grid does not recognise (as a prop-spreading wrapper might add),
    // surfacing warnings #307 (per property) and #310 (summary) in the overlay.
    { field: "make", notAColumnProperty: true } as ColDef,
    { field: "model" },
    { field: "price" },
  ],
  rowData: [
    { make: "Tesla", model: "Model Y", price: 64950 },
    { make: "Ford", model: "F-Series", price: 33850 },
    { make: "Toyota", model: "Corolla", price: 29600 },
  ],
};

let api: GridApi;

api = createGrid(document.querySelector<HTMLElement>("#myGrid")!, gridOptions);
```

[Live example: Overlay](https://www.ag-grid.com/archive/36.2.0/examples/dev-validation/overlay/typescript/)

Each grid shows only its own diagnostics. A nested grid (such as a detail grid in a [Master / Detail](https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/master-detail/) grid) surfaces its diagnostics on its own overlay, not the parent's. When grid creation fails before the grid exists (for example, a row model with no row-model module registered) there is no grid to overlay. A standalone panel is shown in its place.

### Throwing on Problems

`throwOn` turns matching diagnostics into thrown errors instead of console messages, so problems fail fast rather than scrolling past unnoticed. This suits automated workflows (for example, end-to-end test runs or AI-assisted development) where a hard failure is surfaced to be acted on immediately.

Set `throwOn` to an array of the [severities](https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/dev-validation/#overlay) to throw on. For example, to throw on errors only:

```js
enableDevValidations({ throwOn: ['error'] });
```

Defaults to `[]` (never throws).

`throwOn` throws synchronously wherever a matching diagnostic is raised. That is not only at start-up, it also happens during API calls, data updates, and rendering. A throw can interrupt an operation part-way and leave the grid in an inconsistent state. Use `throwOn` with harnesses that recreate the grid on failure rather than carrying on with the same instance, and never in production.

### Reacting to Diagnostics in Code

The `issueRaised` event fires for every captured diagnostic, so tooling can react to problems programmatically instead of watching the console. This suits CI gates, test harnesses and AI-assisted development loops that need to collect diagnostics and act on them.

```js
const gridOptions = {
    onIssueRaised: (event) => {
        // { id: 307, severity: 'warning', message: '...', attributedToThisGrid: true }
        collectForReport(event);
    },
};
```

As with any grid event, you can also subscribe with the API:

```js
api.addEventListener('issueRaised', (event) => collectForReport(event));
```

The event provides:

- `id` — the diagnostic's number, as shown in the console message and the overlay, for example `307`
- `severity` — one of the [severities](https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/dev-validation/#overlay) above
- `message` — the diagnostic text, as written to the console at that severity
- `attributedToThisGrid` — whether this grid raised the diagnostic (see below)

Like the rest of development validation, the event needs the `ValidationModule` registered. Without it no diagnostics are captured, so the callback is inert rather than an error — a callback left in a production build costs nothing but never fires.

The event is not filtered by `showOverlayOn` or `throwOn`: it fires for every diagnostic regardless of which are shown in the overlay, and it fires before a matching `throwOn` throws. Diagnostics you have [suppressed](https://www.ag-grid.com/archive/36.2.0/javascript-data-grid/dev-validation/#suppressing-diagnostics) do not fire the event, as suppressing an id opts out of it entirely.

In the example below, a column definition includes a property the grid does not recognise, and the resulting diagnostics are listed under the grid:

#### Reacting to Diagnostics

```ts
import {
  AllCommunityModule,
  ColDef,
  GridApi,
  GridOptions,
  IssueRaisedEvent,
  ModuleRegistry,
  createGrid,
  enableDevValidations,
} from "ag-grid-community";

// The overlay is turned off so that the diagnostics reaching the callback are the only thing on show.
if (process.env.NODE_ENV !== "production") {
  enableDevValidations({ showOverlayOn: [] });
}

ModuleRegistry.registerModules([AllCommunityModule]);

function onIssueRaised(event: IssueRaisedEvent) {
  const item = document.createElement("li");
  item.textContent = `#${event.id} (${event.severity}): ${event.message}`;
  document.querySelector("#issueList")!.appendChild(item);
}

const gridOptions: GridOptions = {
  columnDefs: [
    // A stray property the grid does not recognise (as a prop-spreading wrapper might add),
    // surfacing warnings #307 (per property) and #310 (summary).
    { field: "make", notAColumnProperty: true } as ColDef,
    { field: "model" },
    { field: "price" },
  ],
  rowData: [
    { make: "Tesla", model: "Model Y", price: 64950 },
    { make: "Ford", model: "F-Series", price: 33850 },
    { make: "Toyota", model: "Corolla", price: 29600 },
  ],
  onIssueRaised,
};

let api: GridApi;

api = createGrid(document.querySelector<HTMLElement>("#myGrid")!, gridOptions);
```

[Live example: Reacting to Diagnostics](https://www.ag-grid.com/archive/36.2.0/examples/dev-validation/issue-raised/typescript/)

The same diagnostic can be raised more than once. The event fires each time, so deduplicate in your handler if you only want each distinct problem once:

```js
const seen = new Set();
const gridOptions = {
    onIssueRaised: (event) => {
        const key = `${event.severity}#${event.id}:${event.message}`;
        if (!seen.has(key)) {
            seen.add(key);
            collectForReport(event);
        }
    },
};
```

Some diagnostics cannot be attributed to a particular grid — a theme created outside any grid, or an API call on a grid that has already been destroyed. These are delivered to every live grid with `attributedToThisGrid: false`. Check the flag if you only want this grid's own problems.

Diagnostics raised before the grid exists — such as a row model with no row-model module registered, which stops the grid being created at all — are reported to the console and the standalone panel, but not through this event, as there is no grid to fire it from.

### Suppressing Diagnostics

> **Warning**
>
> Suppressing diagnostics hides real problems and is a last resort. Reach for it only when the cause is outside your control, for example: a third-party wrapper you cannot change

`suppress` takes the error ids to ignore, for diagnostics you have reviewed and accepted. A suppressed id is kept out of the overlay and is never thrown by `throwOn`, but is still logged to the console once. Suppression is by id, so it silences every diagnostic with that number — not one specific occurrence.

For example, a third-party wrapper you cannot change spreads unrelated props onto your column definitions, so the grid reports properties it does not recognise — a per-property warning (`307`) and a summary (`310`). Suppress both while the source is out of your control:

```js
enableDevValidations({
    suppress: [
        307, // "did you mean …" raised for each unrecognised property
        310, // the "one or more properties are not recognised" summary
    ],
});
```

The id is the number shown in the console message and the overlay, for example `#310`.
