Skip to content

Bugfix in the absorbTicker method#181706

Merged
auto-submit[bot] merged 4 commits intoflutter:masterfrom
nate-thegrate:ticker-resync-bugfix
Feb 25, 2026
Merged

Bugfix in the absorbTicker method#181706
auto-submit[bot] merged 4 commits intoflutter:masterfrom
nate-thegrate:ticker-resync-bugfix

Conversation

@nate-thegrate
Copy link
Contributor

Currently, absorbTicker assumes that between _future and _startTime, if one of them is null and the other is not then the ticker must have been disposed of.

void absorbTicker(Ticker originalTicker) {
assert(!isActive);
assert(_future == null);
assert(_startTime == null);
assert(_animationId == null);
assert(
(originalTicker._future == null) == (originalTicker._startTime == null),
'Cannot absorb Ticker after it has been disposed.',
);

I discovered that starting an animation and then immediately calling resync() leads to a false positive, so this PR tweaks the absorbTicker method accordingly.


resolves #181699

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. a: animation Animation APIs labels Jan 30, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request aims to fix a bug in the absorbTicker method where an assertion would incorrectly fail if resync was called on an AnimationController immediately after starting an animation. A test case is added to cover this scenario.

While the change correctly handles the reported case, the new assertion logic appears to be flawed. It would cause an assertion failure when trying to absorb a ticker that is already actively ticking, which is a valid use case. It also fails to detect a disposed ticker, which is the original purpose of the assertion. I've left a comment with a suggested correction to the assertion logic that should cover all cases correctly.

assert(_animationId == null);
assert(
(originalTicker._future == null) == (originalTicker._startTime == null),
(originalTicker._future != null) || (originalTicker._startTime == null),
Copy link
Contributor

Choose a reason for hiding this comment

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

This makes sense to me, _future can be null (so the ticker is disposed and so _startTime must be null). But _startTime can be null even when _future is non-null.

Copy link
Contributor

Choose a reason for hiding this comment

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

The logical difference before/after is that after, this case does not trigger the assertion:

originalTicker._future != null && originalTicker._startTime == null

That seems to make sense because that's not the case after dispose, it's the case when you create the Ticker and then pass it to absorbTicker before starting it, which seems to be exactly what @nate-thegrate describes in the issue.

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

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

LGTM 👍

assert(_animationId == null);
assert(
(originalTicker._future == null) == (originalTicker._startTime == null),
(originalTicker._future != null) || (originalTicker._startTime == null),
Copy link
Contributor

Choose a reason for hiding this comment

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

The logical difference before/after is that after, this case does not trigger the assertion:

originalTicker._future != null && originalTicker._startTime == null

That seems to make sense because that's not the case after dispose, it's the case when you create the Ticker and then pass it to absorbTicker before starting it, which seems to be exactly what @nate-thegrate describes in the issue.

@justinmc justinmc added the autosubmit Merge PR when tree becomes green via auto submit App label Feb 25, 2026
@auto-submit auto-submit bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Feb 25, 2026
@auto-submit
Copy link
Contributor

auto-submit bot commented Feb 25, 2026

autosubmit label was removed for flutter/flutter/181706, because The base commit of the PR is older than 7 days and can not be merged. Please merge the latest changes from the main into this branch and resubmit the PR.

@victorsanni victorsanni added the autosubmit Merge PR when tree becomes green via auto submit App label Feb 25, 2026
@auto-submit auto-submit bot added this pull request to the merge queue Feb 25, 2026
Merged via the queue into flutter:master with commit 965b5fa Feb 25, 2026
74 checks passed
@flutter-dashboard flutter-dashboard bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Feb 25, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 26, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 26, 2026
ahmedsameha1 pushed a commit to ahmedsameha1/flutter that referenced this pull request Feb 27, 2026
Currently, `absorbTicker` assumes that between `_future` and
`_startTime`, if one of them is null and the other is not then the
ticker must have been disposed of.


https://github.com/flutter/flutter/blob/9b6f15e67d181fcbc4e3ccc7387aa0da8a3d19e6/packages/flutter/lib/src/scheduler/ticker.dart#L329-L337

I discovered that starting an animation and then immediately calling
`resync()` leads to a false positive, so this PR tweaks the
`absorbTicker` method accordingly.

<br>

resolves flutter#181699

---------

Co-authored-by: Victor Sanni <victorsanniay@gmail.com>
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 27, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: animation Animation APIs framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AnimationController resync() sometimes throws an assertion error

3 participants