Dev-time Validation
The grid checks your configuration and tells you when something cannot work. This page explains what it checks, which messages reach your users' browsers and which do not, and why the grid warns instead of throwing.
Two kinds of message
Every console message the grid emits is one of two things, and the difference decides where it prints:
| Diagnostic | Problem | |
|---|---|---|
| About | the configuration you wrote | something that went wrong while running |
| When it can first happen | the first time you run the app | possibly only in production, with real data |
| Prints in development | yes | yes |
| Prints in a production build | no | yes |
The reasoning is simple: advice you can act on belongs in your console, not in the console of someone using your application, who cannot do anything about it. But a dropped row, a suspended gesture or a callback that threw is a real event — and production is the first place most of them can occur, so silencing them there would be hiding exactly the thing worth knowing.
Diagnostics — development only
These describe your configuration. Every one is a pure function of the options you passed, so if it can happen in production it has already happened on your machine:
- Two features that cannot both apply —
treeDatawithgrouping, grouping or tree data inside a board view, auto row height with virtual paging. - Client-side filtering asked for in a mode that only holds part of the data.
- Contradictory grouping defaults, or a group expansion option that a lazy source cannot honour.
- Option values that are not usable — an empty CSV delimiter, a negative condition limit.
- Advice about scale — an editor list large enough to be worth narrowing.
- A no-op call, such as a bulk action invoked with nothing selected.
// Two features that cannot both apply. The grid picks one and says so.
config = {
treeData: { childrenField: 'children' },
grouping: { groupBy: 'department' }, // ← ignored
};
// Console, development build:
// [gridcraft] `treeData` and `grouping` are mutually exclusive — treeData takes
// precedence; grouping ignored.Each fires once per grid, not once per render, and names the option that won so you know what the grid actually did.
Problems — always
These print in every build, production included. They fall into four groups:
- Something you sent was dropped. A transaction that could not be applied, a queue of live updates that overflowed, an update that matched no row because row identity is not configured.
- Something you asked for did not happen. A print with no visible columns, an export whose scope could not be honoured, a saved view that could not be restored, a drag suspended because the view is derived.
- One of your callbacks threw. A
valueFormatter, a tooltip function, a validation rule, a group-expansion predicate. The grid catches it, falls back, and names the column — because a formatter that works on row 1 and throws on row 40,000 is a production event by definition. - Licensing and security. A paid feature used without a licence, a licence key compiled into a client bundle, a validation endpoint that is not HTTPS.
// A transaction the grid cannot honour. This one prints in production too,
// because it is the only signal that rows you sent were dropped.
grid.applyTransaction({ add: [newRow] }); // with scrollMode: 'virtual-paging'
// [gridcraft] applyTransaction: tx.add is not supported with scrollMode:
// "virtual-paging" — inserted rows would misalign the sparse page offsets.
// The add was ignored; new rows appear on the next refetch.// The most common one worth catching early.
grid.applyTransaction({ update: [{ id: 7, status: 'paid' }] });
// [gridcraft] applyTransaction(): update/remove match rows by id, but no row
// identity is configured — set config.trackBy to the id field (e.g. trackBy: "id"),
// otherwise these transactions match no row and are ignored.Every message is prefixed
All of them start with [gridcraft], or [@gridcraft/enterprise] for the licensing ones, so they are easy to filter for — and easy to filter out if you are chasing something else.
The condition a message describes is stable; the sentence is not. Do not assert on the exact wording in tests — assert on the behaviour it describes.
Server-side rendering
During a development SSR run, diagnostics print on the server as well as the browser: the flag that distinguishes a development build is absent there, and the grid treats "unknown" as development rather than staying silent. In a production SSR build the flag is resolved at build time and the server is as quiet as the browser.
Why warnings and not exceptions
Two features that conflict is a design problem, not a data problem. The grid resolves it with a documented precedence rule — one option wins, the other is ignored — and prints which. Throwing would fail the whole page for something the user cannot see and you can fix in a minute. Silently picking one and saying nothing is worse still: that is the behaviour we specifically set out not to have.
Every documented conflict is enforced in code and quoted in the same words the console prints, so a message you see can be traced back to the rule that produced it.