Rules / Style / avoid-non-null-assertion

avoid-non-null-assertion

lint/style/avoid-non-null-assertion
recommended
Same as avoid-non-null-assertion · Dart Code Metrics

Flags the null-assertion operator !.

x! asserts at runtime that x is non-null and throws if it is not, trading a compile-time guarantee for a potential crash. Prefer explicit null handling — ?., ??, an if (x != null) promotion, or restructuring so the value is non-nullable — over silencing the type system. An assertion on a map index (map[key]!) is exempt, since Map's index operator returns a nullable value by design and the assertion is idiomatic there.

Invalid

example.dartdart
// Test cases for avoid-non-null-assertion rule
// All violations are annotated inline

void testNullAssertion() {
  String? nullable = "test";
  final x = nullable!;
  print(x);
}

void printUserName(User? user) {
  print(user!.name);
  print(user!.email);
}

int getValue(int? value) {
  return value! + 10;
}

List<String> getList(List<String>? items) {
  return items!;
}

class Widget {
  String? _title;

  String getTitle() {
    return _title!;
  }

  void render() {
    final context = _context!;
    context.build();
  }
}

Map<String, dynamic> parseResponse(Map<String, dynamic>? data) {
  // The outer index `!` (`[...]!`) is exempt; only `data!` is flagged.
  final nested = data!['key'];
  return nested;
}

Future<String> asyncOperation(Future<String>? future) {
  return future!;
}

void multipleAssertions() {
  final a = value1!;
  final b = value2!;
  final c = (nested!.property)!;
}
Avoid using the null assertion operator '!'
5 String? nullable = "test";
6 final x = nullable!;
Avoid using the null assertion operator '!'
10void printUserName(User? user) {
11 print(user!.name);
Avoid using the null assertion operator '!'
11 print(user!.name);
12 print(user!.email);
Avoid using the null assertion operator '!'
15int getValue(int? value) {
16 return value! + 10;
Avoid using the null assertion operator '!'
19List<String> getList(List<String>? items) {
20 return items!;
Avoid using the null assertion operator '!'
26 String getTitle() {
27 return _title!;
Avoid using the null assertion operator '!'
30 void render() {
31 final context = _context!;
Avoid using the null assertion operator '!'
37 // The outer index `!` (`[...]!`) is exempt; only `data!` is flagged.
38 final nested = data!['key'];
Avoid using the null assertion operator '!'
42Future<String> asyncOperation(Future<String>? future) {
43 return future!;
Avoid using the null assertion operator '!'
46void multipleAssertions() {
47 final a = value1!;
Avoid using the null assertion operator '!'
47 final a = value1!;
48 final b = value2!;
Avoid using the null assertion operator '!'
48 final b = value2!;
49 final c = (nested!.property)!;
Avoid using the null assertion operator '!'
48 final b = value2!;
49 final c = (nested!.property)!;

Valid

example.dartdart
// Good cases for avoid-non-null-assertion rule
// No violations expected

void testNullCoalescing() {
  String? nullable = "test";
  final x = nullable ?? "default";
  print(x);
}

void printUserName(User? user) {
  if (user != null) {
    print(user.name);
    print(user.email);
  }
}

int getValue(int? value) {
  return (value ?? 0) + 10;
}

List<String> getList(List<String>? items) {
  return items ?? [];
}

class Widget {
  String? _title;

  String getTitle() {
    return _title ?? '';
  }

  void render() {
    final context = _context;
    if (context != null) {
      context.build();
    }
  }
}

Map<String, dynamic> parseResponse(Map<String, dynamic>? data) {
  if (data == null) return {};
  final nested = data['key'];
  return nested is Map<String, dynamic> ? nested : {};
}

Future<String> asyncOperation(Future<String>? future) {
  return future ?? Future.value('');
}

void multipleNullChecks() {
  final a = value1 ?? 'default1';
  final b = value2 ?? 'default2';
  if (nested != null && nested.property != null) {
    final c = nested.property;
  }
}

void guardClauses(String? maybeValue) {
  if (maybeValue == null) return;
  print(maybeValue);
}

// A null-assertion on a (map) index expression is exempt.
int readCount(Map<String, int> counts, List<int> xs) {
  final a = counts['key']!;
  final b = xs[0]!;
  return a + b;
}

class Optional<T> {
  final T? _value;

  Optional(this._value);

  T getOrElse(T defaultValue) => _value ?? defaultValue;

  void ifPresent(void Function(T) callback) {
    if (_value != null) callback(_value as T);
  }
}

How to configure

Set the severity of avoid-non-null-assertion in your falcon.json:

falcon.jsonjson
{
  "linter": {
    "rules": {
      "style": {
        "avoid-non-null-assertion": "error"
      }
    }
  }
}