Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Could not find the correct Provider..." when the DevTools is open #121

Open
bramp opened this issue Sep 14, 2023 · 1 comment
Open

"Could not find the correct Provider..." when the DevTools is open #121

bramp opened this issue Sep 14, 2023 · 1 comment

Comments

@bramp
Copy link

bramp commented Sep 14, 2023

I spent a hour or two trying to debug this, but sadly I am no closer :(

When the Flutter DevTools Performance Tools are open, and I am running the storybook in Profile mode (e.g flutter run --profile), I get the following exception when I click on any Story:

I/flutter ( 4503): Error: Could not find the correct Provider<DeviceFrameDataNotifier> above this SingleChildBuilder Widget
I/flutter ( 4503):
I/flutter ( 4503): This happens because you used a `BuildContext` that does not include the provider
I/flutter ( 4503): of your choice. There are a few common scenarios:
I/flutter ( 4503):
I/flutter ( 4503): - You added a new provider in your `main.dart` and performed a hot-reload.
I/flutter ( 4503):   To fix, perform a hot-restart.
I/flutter ( 4503):
I/flutter ( 4503): - The provider you are trying to read is in a different route.
I/flutter ( 4503):
I/flutter ( 4503):   Providers are "scoped". So if you insert of provider inside a route, then
I/flutter ( 4503):   other routes will not be able to access that provider.
I/flutter ( 4503):
I/flutter ( 4503): - You used a `BuildContext` that is an ancestor of the provider you are trying to read.
I/flutter ( 4503):
I/flutter ( 4503):   Make sure that SingleChildBuilder is under your MultiProvider/Provider<DeviceFrameDataNotifier>.
I/flutter ( 4503):   This usually happens when you are creating a provider and trying to read it immediately.
I/flutter ( 4503):
I/flutter ( 4503):   For example, instead of:
I/flutter ( 4503):
I/flutter ( 4503):   ```
I/flutter ( 4503):   Widget build(BuildContext context) {
I/flutter ( 4503):     return Provider<Example>(
I/flutter ( 4503):       create: (_) => Example(),
I/flutter ( 4503):       // Will throw a ProviderNotFoundError, because `context` is associated
I/flutter ( 4503):       // to the widget that is the parent of `Provider<Example>`
I/flutter ( 4503):       child: Text(context.watch<Example>().toString()),
I/flutter ( 4503):     );
I/flutter ( 4503):   }
I/flutter ( 4503):   ```
I/flutter ( 4503):
I/flutter ( 4503):   consider using `builder` like so:
I/flutter ( 4503):
I/flutter ( 4503):   ```
I/flutter ( 4503):   Widget build(BuildContext context) {
I/flutter ( 4503):     return Provider<Example>(
I/flutter ( 4503):       create: (_) => Example(),
I/flutter ( 4503):       // we use `builder` to obtain a new `BuildContext` that has access to the provider
I/flutter ( 4503):       builder: (context, child) {
I/flutter ( 4503):         // No longer throws
I/flutter ( 4503):         return Text(context.watch<Example>().toString());
I/flutter ( 4503):       }
I/flutter ( 4503):     );
I/flutter ( 4503):   }
I/flutter ( 4503):   ```
I/flutter ( 4503):
I/flutter ( 4503): If none of these solutions work, consider asking for help on StackOverflow:
I/flutter ( 4503): https://stackoverflow.com/questions/tagged/flutter
I/flutter ( 4503):
I/flutter ( 4503): #0      Provider._inheritedElementOf (package:provider/src/provider.dart:343)
I/flutter ( 4503): #1      Provider.of (package:provider/src/provider.dart:293)
I/flutter ( 4503): #2      WatchContext.watch (package:provider/src/provider.dart:693)
I/flutter ( 4503): #3      _buildStoryWrapper (package:storybook_flutter/src/plugins/device_frame.dart:28)
I/flutter ( 4503): #4      SingleChildBuilder.buildWithChild (package:nested/nested.dart:361)
I/flutter ( 4503): #5      SingleChildStatelessElement.build (package:nested/nested.dart:277)
I/flutter ( 4503): #6      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5297)
I/flutter ( 4503): #7      Element.rebuild (package:flutter/src/widgets/framework.dart:5016)
I/flutter ( 4503): #8      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:5279)
I/flutter ( 4503): #9      ComponentElement.mount (package:flutter/src/widgets/framework.dart:5273)
I/flutter ( 4503): #10     SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222)
I/flutter ( 4503): #11     Element.inflateWidget (package:flutter/src/widgets/framework.dart:4182)
I/flutter ( 4503): #12     Element.updateChild (package:flutter/src/widgets/framework.dart:3707)
I/flutter ( 4503): #13     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322)
I/flutter ( 4503): #14     Element.rebuild (package:flutter/src/widgets/framework.dart:5016)
I/flutter ( 4503): #15     ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:5279)
I/flutter ( 4503): #16     ComponentElement.mount (package:flutter/src/widgets/framework.dart:5273)
I/flutter ( 4503): #17     _NestedHookElement.mount (package:nested/nested.dart:187)
I/flutter ( 4503): #18     Element.inflateWidget (package:flutter/src/widgets/framework.dart:4182)
I/flutter ( 4503): #19     Element.updateChild (package:flutter/src/widgets/framework.dart:3707)
I/flutter ( 4503): #20     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322)
I/flutter ( 4503): #21     Element.rebuild (package:flutter/src/widgets/framework.dart:5016)
I/flutter ( 4503): #22     ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:5279)
I/flutter ( 4503): #23     ComponentElement.mount (package:flutter/src/widgets/framework.dart:5273)
I/flutter ( 4503): #24     SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222)
I/flutter ( 4503): #25     Element.inflateWidget (package:flutter/src/widgets/framework.dart:4182)
I/flutter ( 4503): #26     Element.updateChild (package:flutter/src/widgets/framework.dart:3707)
I/flutter ( 4503): #27     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322)
I/flutter ( 4503): #28     Element.rebuild (package:flutter/src/widgets/framework.dart:5016)
I/flutter ( 4503): #29     ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:5279)
I/flutter ( 4503): #30     ComponentElement.mount (package:flutter/src/widgets/framework.dart:5273)
I/flutter ( 4503): #31     Element.inflateWidget (package:flutter/src/widgets/framework.dart:4182)
I/flutter ( 4503): #32     Element.updateChild (package:flutter/src/widgets/framework.dart:3701)
I/flutter ( 4503): #33     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322)
I/flutter ( 4503): #34     Element.rebuild (package:flutter/src/widgets/framework.dart:5016)
I/flutter ( 4503): #35     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2779)
I/flutter ( 4503): #36     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:916)
I/flutter ( 4503): #37     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:360)
I/flutter ( 4503): #38     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1297)
I/flutter ( 4503): #39     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1227)
I/flutter ( 4503): #40     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1085)
I/flutter ( 4503): #41     _invoke (dart:ui/hooks.dart:170)
I/flutter ( 4503): #42     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:401)
I/flutter ( 4503): #43     _drawFrame (dart:ui/hooks.dart:140)

When I switch back to a debug build, or close the dev tools, the issue goes away.

Steps to repeat:

flutter run --profile
# It will print something like
# The Flutter DevTools debugger and profiler on sdk gphone64 arm64 is available at: http://127.0.0.1:9101?uri=...

Visit the URL in your browser. Now click on a story, and the exception is thrown. The same occurs if using the DevTools via say VSCode. If you don't open the dev tools, then everything seems fine.

@bramp
Copy link
Author

bramp commented Sep 14, 2023

I did notice, when I'm in profile, the main runApp widget get's built twice, for example:

void main() {
  runApp(const _StoryBookApp());
}

class _StoryBookApp extends StatelessWidget {
  Widget build(BuildContext context) {
    print("build");
    return Storybook(
      ...
    )
  }
}

When I do MediaQuery.of(context), the first context has a size of Zero, whereas the 2nd time it looks correct. I don't see this pattern when the DevTools are closed. Changing my code to:

  Widget build(BuildContext context) {
    if (MediaQuery.of(context).size.isEmpty) {
      return const Placeholder();
    }
    return Storybook(...);
  }

Seems to actually fix my problem! So ok, this makes me think, somewhere in Storybook something is being cached, and triggering this mess.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant