Rules / Style / unnecessary-late

unnecessary-late

lint/style/unnecessary-late
recommended
Same as unnecessary_late · Dart lints

Flags a redundant late modifier on an initialized static or top-level variable.

Static fields and top-level variables in Dart are already initialized lazily: their initializer does not run until the variable is first read. Marking such a declaration late therefore buys nothing, and it misleads readers into thinking deferred initialization is significant here. The rule only fires when the declarator actually has an initializer, since late on an uninitialized static or top-level variable does carry meaning. Drop the late keyword.

Invalid

example.dartdart
// `late` on already-lazy static / top-level variables with initializers.
late String banner = 'hello';
late int total = compute();

// `late final` with an initializer is equally redundant: static / top-level
// finals are already lazily initialized, so `late` still adds nothing.
late final int cachedTotal = compute();

int compute() => 42;

class Service {
  static late Service instance = Service._();
  static late int counter = 0;
  static late final int cached = 0;
  Service._();
}

class Cache {
  static late String key = 'k';
  static late bool ready = true;
}
Unnecessary 'late' on an already-lazy static or top-level variable.
1// `late` on already-lazy static / top-level variables with initializers.
2late String banner = 'hello';
Unnecessary 'late' on an already-lazy static or top-level variable.
2late String banner = 'hello';
3late int total = compute();
Unnecessary 'late' on an already-lazy static or top-level variable.
6// finals are already lazily initialized, so `late` still adds nothing.
7late final int cachedTotal = compute();
Unnecessary 'late' on an already-lazy static or top-level variable.
11class Service {
12 static late Service instance = Service._();
Unnecessary 'late' on an already-lazy static or top-level variable.
12 static late Service instance = Service._();
13 static late int counter = 0;
Unnecessary 'late' on an already-lazy static or top-level variable.
13 static late int counter = 0;
14 static late final int cached = 0;
Unnecessary 'late' on an already-lazy static or top-level variable.
18class Cache {
19 static late String key = 'k';
Unnecessary 'late' on an already-lazy static or top-level variable.
19 static late String key = 'k';
20 static late bool ready = true;

Valid

example.dartdart
// `late` that is genuinely needed, or plain declarations.
late final String deferred;

String loadConfig() => 'cfg';

class Service {
  late final Service instance;
  static final ready = true;
  static int counter = 0;
  late int lazyInstanceField = 1;
  Service();
}

final topLevel = loadConfig();
String plain = 'x';

How to configure

Set the severity of unnecessary-late in your falcon.json:

falcon.jsonjson
{
  "linter": {
    "rules": {
      "style": {
        "unnecessary-late": "error"
      }
    }
  }
}