avoid_non_null_assertion
This rule flags every use of the null-assertion operator !.
Why use this rule
Section titled “Why use this rule”! is not a check — it is an unchecked assertion. It tells the compiler a value is non-null and throws a TypeError at runtime when that turns out to be wrong.
The type system stops helping at exactly the point the value is most likely to be null. Every other tool Dart gives you for nullability — ?., ??, a null check, pattern matching — either handles the null case or makes the compiler prove it cannot happen. ! alone converts a question the analyser could have answered into a production crash.
See also: Understanding null safety, Sound null safety
// Throws if `user` is null — nothing checked it.user!.name;
// Chained bangs compound the risk: either one can throw.config.timeout!.inSeconds;
fetchAccount()!.close();// Short-circuit instead of throwing.user?.name;
// Supply a fallback.final seconds = config.timeout?.inSeconds ?? 0;
// Or narrow with a check, so the compiler proves it.if (user != null) { print(user.name);}Reading a known-present entry out of a Map is exempt by default, because Map’s index operator is declared nullable no matter what the map holds. The pedantic preset disables this exception and therefore bans every postfix !:
// Not reported.translations['title']!.toUpperCase();Relationship to the official Dart lints
Section titled “Relationship to the official Dart lints”The SDK linter has no equivalent rule — a request for one (sdk#59476) was closed without shipping. Two official rules cover strict subsets of what this rule reports, so enabling both means those cases are reported twice:
| Official rule | Overlap |
|---|---|
unnecessary_null_checks |
Flags only bangs whose surrounding context already accepts null — the redundant ones |
null_check_on_nullable_type_parameter |
Flags only a bang on a potentially nullable generic type parameter |
If the duplicate diagnostics bother you, disable the narrower SDK rules — this rule already reports everything they do.
Known limitations
Section titled “Known limitations”There is deliberately no quick fix. Rewriting ! to ?. changes behaviour: an expression that used to throw would instead silently evaluate to null, which moves the failure somewhere else rather than fixing it. Choosing between ?., ??, a guard, or restructuring the types is a judgement call the author has to make.
For the common case of a ! on a field inside an if (field != null) guard, two assists do the rewrite for you — Convert null check to pattern (semantics-preserving) and Convert null check to destructuring pattern (narrows the condition). They are assists rather than fixes because both restructure the whole if, above the node this rule reports on.
A ! inside a pattern (case var x!) is a NullAssertPattern, not the postfix operator, and is not reported.
Turning this rule off
Section titled “Turning this rule off”This rule is in the opinionated preset, so it is on with
preset: opinionated, or by name:
rules: avoid_non_null_assertion: trueTo turn it off again:
rules: avoid_non_null_assertion: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Options
Section titled “Options”many_lints: rules: avoid_non_null_assertion: ignore_checked_fields: true ignore_map_indexes: falserules: avoid_non_null_assertion: ignore_checked_fields: true ignore_map_indexes: false| Option | Type | Default | Description |
|---|---|---|---|
ignore_checked_fields |
bool | false |
Don’t report a ! on a field an enclosing if (field != null) already checked. Off by default because type promotion does not apply to fields — the bang is genuinely what makes the code compile, and the field can still change between the check and the use |
ignore_map_indexes |
bool | true |
Allow the idiomatic map[key]! spelling. The pedantic preset changes this default to false |
Related rules
Section titled “Related rules”function_always_returns_null— A nullable-returning function whose every path returns null.avoid_accessing_other_classes_private_members— Make the underscore mean what everyone reads it as.avoid_commented_out_code— Detect and flag commented-out code.avoid_complex_conditions— Keep boolean conditions within an operand budget.