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

Invalid argument: Maximum call stack size exceeded (bug in dart compiler) #1713

Closed
TreyThomas93 opened this issue Oct 2, 2022 · 26 comments · Fixed by #1823
Closed

Invalid argument: Maximum call stack size exceeded (bug in dart compiler) #1713

TreyThomas93 opened this issue Oct 2, 2022 · 26 comments · Fixed by #1823
Labels
bug Something isn't working dart-bug Marks a bug that is actually a bug in the dart or flutter tooling

Comments

@TreyThomas93
Copy link

TreyThomas93 commented Oct 2, 2022

Edit: This is a dart web compiler bug, only for the debug web compiler, you can get around it by developing on desktop and testing / deploying a release build on web.
Upvote this issue: dart-lang/sdk#50119

Describe the bug
Getting this error for Flutter web with Riverpod version 2.0:

 Invalid argument: Maximum call stack size exceeded
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ #0   packages/riverpod/src/framework/auto_dispose.dart 7:24                                                            <computed>
│ #1   packages/riverpod/src/provider/base.dart 259:27                                                                   __
│ #2   packages/riverpod/src/provider/auto_dispose.dart 34:7     

Version 1.0.3 worked fine on web, but using version 2.0 seems to be giving me this error.
No issues found on Android/iOS. Just web so far.

To Reproduce
I am not really sure how to reproduce this for the provider file is quite lengthy. I am actively looking for the source but thought I should post this for the time being.

@TreyThomas93 TreyThomas93 added bug Something isn't working needs triage labels Oct 2, 2022
@TreyThomas93
Copy link
Author

I have been able to pinpoint where the error is occurring. It appears that if I am watching a provider in more than one place within the same widget, and the provider is using .autoDispose, then it will result in the error. Removing .autoDispose fixes the issue. As I said, this is only happening on Flutter web.

After "fixing" that, I noticed the same issue was occurring when I called .listen on a provider, regardless if it had .autoDispose added to it.

Calls This

ref.listen(firstPhaseProvider, (_, bool isComplete) async {
            if (isComplete == true) {
              // Fire off second phase
              await Future.wait([
                ref
                    .read(sessionsSyncProvider.notifier)
                    .fetchSessionsFromServer(),
                // ref
                //     .read(weeklistsSyncProvider.notifier)
                //     .fetchWeeklistFromServer(),
                ref
                    .read(supervisorsSyncProvider.notifier)
                    .fetchSupervisorsFromServer(),
              ]);
            }
          });

final firstPhaseProvider = Provider.autoDispose<bool>((ref) {
  final servicesDone = ref.watch(servicesSyncProvider);
  final patientsDone = ref.watch(patientsSyncProvider);
  final referralsDone = ref.watch(pendingReferralsSyncProvider);

  if (servicesDone != const SyncStatus.syncing() &&
      patientsDone != const SyncStatus.syncing() &&
      referralsDone != const SyncStatus.syncing()) {
    return true;
  }

  return false;
}, name: "FirstPhaseProvider");

Gets This

 Invalid argument: Maximum call stack size exceeded
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ #0   packages/riverpod/src/framework/auto_dispose.dart 7:24                                                           <computed>
│ #1   packages/riverpod/src/provider/base.dart 259:27                                                                  __
│ #2   packages/riverpod/src/provider/auto_dispose.dart 34:7    

@TreyThomas93
Copy link
Author

It appears that if I am watching any provider with an .autoDispose that it is giving me this error. Flutter Web

@7mada123
Copy link

7mada123 commented Oct 2, 2022

I'm facing the same issue

@JulianSwales
Copy link

I am having the same issue. I have a sample app here with it failing. https://github.com/JulianSwales/test_web

@rich-j
Copy link

rich-j commented Oct 2, 2022

2.0.0-dev.9 worked on the web, 2.0.1 fails as shown above. iOS is fine on both versions.

@deyjishnu
Copy link

deyjishnu commented Oct 3, 2022

2.0.0-dev.9 worked on the web, 2.0.1 fails as shown above. iOS is fine on both versions.

I confirm the same. Facing the issue on web with versions 2.0.1 and 2.0.0, but 2.0.0-dev.9 and 1.0.3 works

@TimWhiting
Copy link
Collaborator

TimWhiting commented Oct 3, 2022

From git-bisect the breaking commit was this one:
f36e968

Note that this could be an issue with dart's web compiler and not a problem with riverpod. We'll have to try to figure out a smaller example (ideally without the flutter dependency, and likely without all of the riverpod machinery) if we want the dart team to quickly resolve the issue if it is a problem with the dart compiler.

A minimal reproduction flutter riverpod sample, taken from the flutter riverpod example (just changing the provider to autoDispose).

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

// A Counter example implemented with riverpod

void main() {
  runApp(
    // Adding ProviderScope enables Riverpod for the entire project
    const ProviderScope(child: MyApp()),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: Home());
  }
}

/// Providers are declared globally and specify how to create a state
final counterProvider = StateProvider.autoDispose((ref) => 0);

class Home extends ConsumerWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter example')),
      body: Center(
        // Consumer is a widget that allows you reading providers.
        child: Consumer(
          builder: (context, ref, _) {
            final count = ref.watch(counterProvider.state).state;
            return Text('$count');
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        // The read method is a utility to read a provider without listening to it
        onPressed: () => ref.read(counterProvider.state).state++,
        child: const Icon(Icons.add),
      ),
    );
  }
}

@TimWhiting
Copy link
Collaborator

TimWhiting commented Oct 3, 2022

The dart web-simple template with the following reproduces the error.

import 'dart:html';
import 'package:riverpod/riverpod.dart';

void main() {
  final container = ProviderContainer();
  final value = container.read(stringValue.state);
  querySelector('#output')?.text = 'Your ${value.state} app is running.';
  final _ = container.listen(stringValue.state, (_, value) {
    querySelector('#output')?.text = 'Your ${value.state} app is running.';
  }, fireImmediately: true);
}

final stringValue = StateProvider.autoDispose((ref) => 'Hello world');

@schultek
Copy link

schultek commented Oct 3, 2022

It is reproducible without flutter using the dart web-simple template and the following snippet:

import 'dart:html';
import 'package:riverpod/riverpod.dart';

void main() {
  final container = ProviderContainer();
  final value = container.read(stringValue.state);

  querySelector('#output')?.text = 'Your ${value.state} app is running.';

  final sub = container.listen(stringValue.state, (_, value) {
    querySelector('#output')?.text = 'Your ${value.state} app is running.';
  }, fireImmediately: true);

  container.read(stringValue.notifier).state = 'Hello changed';

  sub.close();
}

final stringValue = StateProvider.autoDispose((ref) => 'Hello world');

My guess is that without actually disposing the provider, the dart compiler optimizes out all of the related code from riverpod, thats why @TimWhiting s snippet worked.

The error / stack trace is:

Uncaught RangeError: Maximum call stack size exceeded
    at set [_keepAliveLinks] (riverpod.sound.ddc.js:9149:38)
    ... (the same line many times)
    at set [_keepAliveLinks] (riverpod.sound.ddc.js:9149:38)
    at AutoDisposeProviderElementMixin.<computed> (riverpod.sound.ddc.js:2041:29)
    at StateProviderElement_AutoDisposeProviderElementMixin$36.__ (riverpod.sound.ddc.js:9137:68)
    at new AutoDisposeStateProviderElement.__ (riverpod.sound.ddc.js:9174:52)
    at AutoDisposeStateProvider.new.createElement (riverpod.sound.ddc.js:8995:16)
    at [_create] (riverpod.sound.ddc.js:4577:44)
    at framework._StateReader.new.getElement (riverpod.sound.ddc.js:4568:60)
    ...

So it seems like the js _keepAliveLinks setter is calling itself recursively.

@TimWhiting
Copy link
Collaborator

Thanks for that @schultek, I actually just realized that I was on the commit prior to the breaking commit when testing the webdev snippet. Was able to reproduce, with just the read on the container.

Filed dart-lang/sdk#50119, since I believe it is a web compiler issue.

@TimWhiting
Copy link
Collaborator

While creating the dart issue, I found that I don't get this error for an AOT web build.

@schultek
Copy link

schultek commented Oct 3, 2022

I found a non-riverpod snippet that reproduces the issue, which I added to the ticket. So this can possibly be closed.

@rrousselGit
Copy link
Owner

Thank you all for your investigation.

That pure Dart example posted in the related issue is quite a funky one.

@Patrick386
Copy link

Flutter Web:
Same error, version 1.0.3 worked fine on the web, but when I use version 2.0 I get this error.

@bizz84
Copy link
Contributor

bizz84 commented Oct 4, 2022

I can confirm what everyone else is saying. Using .autoDispose on Flutter web breaks the app on Riverpod 2.0.1 (but not on the previous dev releases).

I understand that this is a Dart SDK issue.

Though presumably the next Dart stable release could be months away and as it stands all apps using autoDispose with Riverpod 2.0 will break on web.

What is the recommended "patch" for now? Revert to Riverpod 2.0.0-dev.9 or wait for a new minor release with a workaround?

@rrousselGit
Copy link
Owner

Well first it'd be nice to have a reply from the Dart team.

It's a bug. So it doesn't have to take months to be released. It could be cherry-picked.
If not, then I'll think of a solution. Although I'd like to avoid having to do a large refactor just because of a Dart bug

@TimWhiting
Copy link
Collaborator

TimWhiting commented Oct 4, 2022

In the meantime, everyone please add a thumbs up to the linked dart issue, to help them prioritize this for a fix and cherry pick.

@schultek Even though this is a dart issue I think we should leave this issue open to make it easier for Riverpod users to find so we don't get duplicate issues opening.

@iLoveDocs
Copy link

Here's the minimal code (if anyone was looking for)

I get the error when I use autoDispose on either the FutureProvider or StreamProvider

void main() => runApp(ProviderScope(child: MaterialApp(home: FooPage())));

class FooPage extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    ref.watch(fooProvider);
    return Container();
  }
}

final fooProvider = FutureProvider.autoDispose<int>((ref) => Future.value(0));

@GregoryConrad
Copy link

For what it is worth, I only had this bug when in debug on web. Release mode seemed to be not affected.

@1l0
Copy link

1l0 commented Oct 8, 2022

Seems to be related:
#1636
#1650

@TimWhiting TimWhiting added dart-bug Marks a bug that is actually a bug in the dart or flutter tooling and removed bug Something isn't working labels Oct 8, 2022
@TimWhiting TimWhiting changed the title Invalid argument: Maximum call stack size exceeded Invalid argument: Maximum call stack size exceeded (bug in dart compiler) Oct 8, 2022
@tomas-carv-com
Copy link

same here ;)

@TreyThomas93
Copy link
Author

Can confirm that this is only an issue when running the app in DEBUG mode. When I run it in RELEASE mode, I do not get the error.

@ShoYakup
Copy link

Here's the minimal code (if anyone was looking for)

I get the error when I use autoDispose on either the FutureProvider or StreamProvider

void main() => runApp(ProviderScope(child: MaterialApp(home: FooPage())));

class FooPage extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    ref.watch(fooProvider);
    return Container();
  }
}

final fooProvider = FutureProvider.autoDispose<int>((ref) => Future.value(0));

@MickyHuyHa
Copy link

MickyHuyHa commented Oct 24, 2022

UPDATE: FAIL

I have a same issue.
I fixed it by upgrade environment version in pubspec.yaml
From:

environment:
  sdk: ">=2.14.0 <3.0.0"

To:

environment:
  sdk: ">=2.17.0 <3.0.0"

@radvansky-tomas
Copy link

That doesnt fix it, at least not on my machine. We run 2.17 for a long time and that issue is there since last upgrade

@leehack
Copy link
Contributor

leehack commented Oct 27, 2022

I added a PR for a fix. I think the fix can be used until the dart team officially fix the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working dart-bug Marks a bug that is actually a bug in the dart or flutter tooling
Projects
None yet
Development

Successfully merging a pull request may close this issue.