Failed assertion: line 3927 pos 14: '_dependents.isEmpty': is not true

I recently had the same exception when I was trying to navigate to another route from a Stateful Widget. Turns out I had forgotten to add the line super.initState(); at the start of my widget's initState()

Once I change it to this it worked perfectly

 @override
  void initState() {
    super.initState();
    ....
  }

For anyone who may find this helpful, I recently had this issue too and it was caused by incorrectly setting a number of key parameters in a list of widgets. I was setting the key based on an id:

key: Key(item.id.toString())

However due to some other logic item.id can sometimes be null and because there are a number of these widgets I ended up with multiple widgets with the key: Key("null"). Updating my key to ensure it was unique solved my problem:

key: Key(items.indexOf(item).toString())

This happened to me as I wrapped a ListView.builder with an Expanded without a container surrounding the Expanded directly as the body of my Scaffold.


This error happens due to incorrect widget configuration, so in other words it's not an error itself, but a symptom of another error.

For OP

OP has already found a solution so I won't elaborate on it. Fixing the error in your ListView should do the trick.

TL;DR

Try:

  • Calling super.initState() inside all your StatefulWidgets.initState() overrides.
  • Making sure all your Widget.keys are unique.
  • Making sure all your widgets that use a builder function have no errors. These widgets include AnimatedBuilder, LayoutBuilder, and external packages like GetX or Provider that have a builder, and any packages that depend on them (like Bloc). With these builder widgets, the exception usually occurs when you build the same Widget with different instance members based on some passed value. For example:
...
BlocBuilder<MyBloc, MyState>(
  builder: (context, state) => Container(
    color: state is SomeState ? Colors.blue : Colors.red, // Something along these lines
  ), 
)

// or
BlocBuilder<MyBloc, MyState>(
  builder: (context, state) => state is SomeState ? Container(color: Colors.red) : Container(color: Colors.blue), 
)
....

More Explanation

First of all, I want to note that while the exception message is a bit misleading, the flutter team had a couple TODOs to make the exception clearer and refer specifically to the faulty widget.

As the message mentions, the error is related to duplicate GlobalKeys within the widget tree. Usually, this doesn't happen due to directly using the same Key on two different widgets (because devs are usually aware of that). Instead, it hides itself behind other issues such as the ones mentioned above. They all produce similar effect, however: They cause errors in the widget's lifecycle state.

Forgetting to call initState, for instance, messes up the widget's lifecycle state update. I'm not exactly sure exactly where this happens, but it seems that the framework creates duplicate element/widget to the same widget with the same GlobalKey if the widget's lifecycle state is tampered with. This needs further investigation and confirmation.

The thing with builder widgets is that if the first widget to be returned from the builder has an exception, the framework will mount it, but for some reason, the lifecycle change will not occur when the second widget to be returned from builder is inserted in the tree, and both the first and the second widgets end up with the same Key.

In both cases, when the framework unmounts currently active widgets, it checks widgets' lifecycle state, determines which ones are inactive, and ignores them. However, because lifecycle states of some widgets are wrong, it might treat an inactive widget as active, compare it to currently active widgets only to find duplicates, and then throw the exception.

If you want to check that yourself, you can read src/widgets/framework.dart file referred to in the error message, starting from BuilderOwner.finalizeTree() function.

Tags:

Dart

Flutter