Skip to content

fixes DrivenScrollActivity LateInitializationError _controller #171616

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

agrapine
Copy link

@agrapine agrapine commented Jul 4, 2025

When we call ScrollController.animateTo(someOffset, duration: Duration.zero) we can end up with an animation tick being handled before the _controller in DrivenScrollActivity is initialised.
Current workaround is to guard against such case, but once in production is basically broken :(

Error:

LateError: LateInitializationError: Field '_controller@375498029' has not been initialized.
#0      DrivenScrollActivity._tick (package:flutter/src/widgets/scroll_activity.dart)
#1      AnimationLocalListenersMixin.notifyListeners (package:flutter/src/animation/listener_helpers.dart:161)
#2      AnimationController._animateToInternal (package:flutter/src/animation/animation_controller.dart:694)
#3      AnimationController.animateTo (package:flutter/src/animation/animation_controller.dart:617)
#4      new DrivenScrollActivity (package:flutter/src/widgets/scroll_activity.dart:718)
#5      ScrollPositionWithSingleContext.animateTo (package:flutter/src/widgets/scroll_position_with_single_context.dart:184)
#6      ScrollController.animateTo (package:flutter/src/widgets/scroll_controller.dart:214)

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests or get an explicit test exemption before merging.

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.If you believe this PR qualifies for a test exemption, contact "@test-exemption-reviewer" in the #hackers channel in Discord (don't just cc them here, they won't see it!). The test exemption team is a small volunteer group, so all reviewers should feel empowered to ask for tests, without delegating that responsibility entirely to the test exemption group.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: scrolling Viewports, list views, slivers, etc. labels Jul 4, 2025
@agrapine
Copy link
Author

agrapine commented Jul 4, 2025

For the tests its a bit difficult, as this is a production only bug. while in debug/test this case is illegal due to asserts.

@agrapine agrapine force-pushed the fix/scrollactivity_uninitialized_field branch 2 times, most recently from 57c1f9a to 24e1b06 Compare July 4, 2025 06:10
@kszczek
Copy link
Contributor

kszczek commented Jul 4, 2025

Nice catch! Although I'm not sure this is meant to be fixed. As far as I can tell this error only happens when a zero duration is specified, and the DrivenScrollActivity actually asserts that duration cannot be zero. If this happens with duration other than zero, then this definitely needs a fix though.

This error occurs because AnimationController is smart, and when it's given a zero duration it won't start a ticker, but will simply invoke the tick callback immediately (and synchronously).

if (simulationDuration == Duration.zero) {
if (value != target) {
_value = clampDouble(target, lowerBound, upperBound);
notifyListeners();
}
_status =
(_direction == _AnimationDirection.forward)
? AnimationStatus.completed
: AnimationStatus.dismissed;
_checkStatusChanged();
return TickerFuture.complete();
}

With that said, there is some space for improvement. We could check if the duration is zero and jump to the target immediately, like so:

--- a/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart
+++ b/packages/flutter/lib/src/widgets/scroll_position_with_single_context.dart
@@ -176,7 +176,7 @@ class ScrollPositionWithSingleContext extends ScrollPosition implements ScrollAc
 
   @override
   Future<void> animateTo(double to, {required Duration duration, required Curve curve}) {
-    if (nearEqual(to, pixels, physics.toleranceFor(this).distance)) {
+    if (nearEqual(to, pixels, physics.toleranceFor(this).distance) || duration == Duration.zero) {
       // Skip the animation, go straight to the position as we are already close.
       jumpTo(to);
       return Future<void>.value();

Here's a minimal reproducible code sample for this error. To trigger it, you have to start it in profile or release mode to disable asserts.

import 'package:flutter/material.dart';

void main() => runApp(const ExampleApp());

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

  @override
  Widget build(final BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        floatingActionButton: Builder(
          builder: (final BuildContext context) => FloatingActionButton(
            onPressed: () {
              const double targetOffset = 500.0;
              PrimaryScrollController.of(context).animateTo(
                targetOffset,
                duration: Duration.zero,
                curve: Curves.easeInOut,
              );
            },
          ),
        ),
        body: ListView.builder(
          primary: true,
          itemBuilder: (_, final int index) {
            final int shade = ((index % 9) + 1) * 100;
            return Container(height: 100, color: Colors.red[shade]!);
          },
        ),
      ),
    );
  }
}

Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @agrapine thanks for contributing! It looks like the is an analyzer failure, and we're missing some tests to verify this change works as expected. Is there an open issue this is looking to resolve? Right now it is hard to say if this is the right fix without more context. Thanks!

@flutter-dashboard
Copy link

This pull request executed golden file tests, but it has not been updated in a while (20+ days). Test results from Gold expire after as many days, so this pull request will need to be updated with a fresh commit in order to get results from Gold.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@agrapine
Copy link
Author

agrapine commented Aug 4, 2025

@kszczek we can definetly jump directly to target and skip the animation.
🤔 it still seems reasonable to to first initialise the _controller before firing animateWith.

@agrapine
Copy link
Author

agrapine commented Aug 4, 2025

Hey @agrapine thanks for contributing! It looks like the is an analyzer failure, and we're missing some tests to verify this change works as expected. Is there an open issue this is looking to resolve? Right now it is hard to say if this is the right fix without more context. Thanks!

i can't find a good doc on how to fix the analyzer issue. sorry (already spent a bit too much time on this)

@Piinks
Copy link
Contributor

Piinks commented Aug 4, 2025

i can't find a good doc on how to fix the analyzer issue. sorry (already spent a bit too much time on this)

Documentation about debugging tests and how to contribute are in all in the repo under docs/.

(already spent a bit too much time on this)

I understand. Thanks for taking the time you did. Does this mean this PR should be closed? It still needs a test in addition to resolving the current failure.

@agrapine agrapine force-pushed the fix/scrollactivity_uninitialized_field branch from 24e1b06 to 7302dbd Compare August 19, 2025 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants