avoid_recursive_widget_calls
This rule flags a widget whose build method unconditionally instantiates the widget’s own type. For a State, it flags construction of the StatefulWidget the state belongs to.
Why use this rule
Section titled “Why use this rule”A widget that builds itself with no terminating condition recurses until the stack overflows. The app crashes the moment the widget is mounted, usually with a Stack Overflow that points deep into the framework rather than at your code.
It is an easy mistake to make during a rename or a copy-paste: return MyWidget() when you meant return MyOtherWidget(), or a State returning its widget instead of its content.
class MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { // Infinite recursion — crashes on mount return MyWidget(); }}class MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return const Text('Hello'); }}
// Recursion with a terminating condition is fineclass TreeNode extends StatelessWidget { const TreeNode(this.depth); final int depth;
@override Widget build(BuildContext context) { if (depth == 0) return const SizedBox(); return TreeNode(depth - 1); }}Known limitations
Section titled “Known limitations”Only unconditional self-construction is reported. Anything inside an if, a ternary, a switch, or a builder: callback is skipped, since those shapes can terminate or build lazily. That keeps genuine recursive tree widgets quiet, at the cost of missing a recursion whose guard never actually terminates.
Turning this rule off
Section titled “Turning this rule off”This rule is in the core preset, so it is on with preset: core,
preset: recommended or preset: opinionated.
To turn it off:
rules: avoid_recursive_widget_calls: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Options
Section titled “Options”Projects with a state abstraction that does not extend Flutter’s State can
opt that base class into this rule:
many_lints: rules: avoid_recursive_widget_calls: state_base_classes: [AppState]rules: avoid_recursive_widget_calls: state_base_classes: [AppState]| Option | Type | Default | Description |
|---|---|---|---|
state_base_classes |
list of strings | [] |
Additional non-State base classes whose subclasses should be treated as state classes |
Related rules
Section titled “Related rules”avoid_deep_widget_nesting— Keep a widget tree within a nesting budget.prefer_single_widget_per_file— Keep one public widget per file for better organization.prefer_widget_private_members— A widget’s public API is its constructor.always_pass_global_key— Don’t create a GlobalKey inside build.