always-pass-global-key
- Group
- Correctness
- Path
lint/correctness/always-pass-global-key- Default
- Off, opt in
- Origin
- Falcon
- Domain
- flutter
- Rule
- 4 of 512
Keep GlobalKeys stable and pass owned State fields to widgets.
Reports nonconstant GlobalKey-subtype constructors directly in widget key
arguments, including outside State classes. Value-stable GlobalObjectKeys,
constant keys and cached field/top-level initializers are exempt. Closures
inside those initializers are still checked. Stored keys are checked only for
concrete Flutter State classes: abstract bases and injected fields are skipped.
Passing a field anywhere in a call argument counts conservatively, since
helpers may attach it to a widget. Shadowed locals and currentState/currentContext
receiver reads do not count as passing the key.
Invalid
import 'package:flutter/material.dart';
import 'package:flutter/material.dart' as f;
typedef FormKey = GlobalKey;
class Missing extends State<Widget> {
final _first = GlobalKey();
final GlobalKey _second = GlobalKey();
final _third = f.GlobalKey();
final _fourth = LabeledGlobalKey('fourth');
final _fifth = FormKey();
final _shadowed = GlobalKey();
final _stateRead = GlobalKey();
final _contextRead = GlobalKey();
void inspect() {
observe(_stateRead.currentState);
observe(this._contextRead.currentContext);
}
Widget build() {
final _shadowed = GlobalKey();
return IconButton(key: _shadowed);
}
}
void observe(Object? value) {}class Missing extends State<Widget> { final _first = GlobalKey(); final _first = GlobalKey(); final GlobalKey _second = GlobalKey(); final GlobalKey _second = GlobalKey(); final _third = f.GlobalKey(); final _third = f.GlobalKey(); final _fourth = LabeledGlobalKey('fourth'); final _fourth = LabeledGlobalKey('fourth'); final _fifth = FormKey(); final _fifth = FormKey(); final _shadowed = GlobalKey(); final _shadowed = GlobalKey(); final _stateRead = GlobalKey(); final _stateRead = GlobalKey(); final _contextRead = GlobalKey();Valid
import 'package:flutter/material.dart';
class Used extends State<Widget> {
final _direct = GlobalKey();
final _helper = GlobalKey();
final _conditional = GlobalKey();
final _inherited = GlobalKey();
final GlobalKey injected;
Used(this.injected);
Widget first() => IconButton(key: this._direct);
void second() => attach(_helper);
void third(bool choose) => attach(choose ? _conditional : null);
}
class Child extends Used {
Child(GlobalKey key) : super(key);
void attachInherited() => attach(_inherited);
}
abstract class Base extends State<Widget> {
final inherited = GlobalKey();
}
class Controller { final key = GlobalKey(); }
class Wrapper extends Widget { final key = GlobalKey(); }
void attach(Object? key) {}
void locals() { final local = GlobalKey(); }Configure always-pass-global-key
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"correctness": {
"always-pass-global-key": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/correctness/always-pass-global-key: <reason>More correctness rules
- always-remove-listenerrecommendedflutter
Requires Flutter Listenable registrations in State to be removed.
- always-use-package-imports
always_use_package_importsDisallow relative imports in libraries under a package's
lib/directory. - avoid-assigning-to-static-field
Flags instance methods writing resolved static fields, including compound assignments and increments.
- avoid-calling-notifier-members-inside-buildrecommendedriverpod
Flags calls to Riverpod notifier methods during widget build.
- avoid-collection-equality-checksrecommended
Flags equality comparisons between non-constant SDK collections.
- avoid-conditional-hooksrecommendedflutter_hooks
Flags hook calls in conditional branches, short-circuit operands, and loops.
- avoid-constant-assert-conditions
Flags assertions whose Boolean condition is statically constant.
- avoid-constant-conditions
Flags statically constant binary branch, loop, collection, and expression conditions.