Skip to content

AnimatedList throws 'itemIndex >= 0 && itemIndex < _itemsCount': is not true. when removing last item while another item is being removed at the moment #186361

Description

@Orillio

Steps to reproduce

  1. Run provided code sample
  2. Press delete icon on any list item, except last one
  3. While delete animation is running - press delete icon on last list item
  4. Observe exception.

The issue is continuation of #176362.
The issue is replicating on AnimatedList.separated version of list.

Expected results

last item should be deleted without exception

Actual results

An exception is thrown

The following assertion was thrown while handling a gesture:
'package:flutter/src/widgets/animated_scroll_view.dart': Failed assertion: line 1398 pos 12: 'itemIndex >= 0 && itemIndex < _itemsCount': is not true.

Code sample

Code sample
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: AnimatedListExample(),
    );
  }
}

class AnimatedListExample extends StatefulWidget {
  const AnimatedListExample({super.key});

  @override
  State<AnimatedListExample> createState() => _AnimatedListExampleState();
}

class _AnimatedListExampleState extends State<AnimatedListExample> {
  final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
  final List<int> _items = List.generate(10, (index) => index);

  void _removeItem(int index) {
    final removedItem = _items[index];
    _listKey.currentState?.removeItem(
      index,
      (context, animation) => SizeTransition(
        sizeFactor: animation,
        child: _buildItem(removedItem, animation, isRemoved: true),
      ),
      // 👇 Long delay so you can press "Remove All" while it’s still animating
      duration: const Duration(seconds: 10),
    );
    _items.removeAt(index);
  }

  void _removeAll() {
    _listKey.currentState?.removeAllItems(
      (context, animation) {
        return SizeTransition(
          sizeFactor: animation,
          child: Container(
            color: Colors.red[100],
            child: const ListTile(
              title: Text("Removing..."),
            ),
          ),
        );
      },
      duration: const Duration(seconds: 2),
    );
    _items.clear();
  }

  Widget _buildItem(
    int item,
    Animation<double> animation, {
    bool isRemoved = false,
  }) {
    return SizeTransition(
      sizeFactor: animation,
      child: Card(
        margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
        child: ListTile(
          title: Text("Item $item"),
          trailing: !isRemoved
              ? IconButton(
                  icon: const Icon(Icons.delete, color: Colors.red),
                  onPressed: () {
                    final index = _items.indexOf(item);
                    if (index != -1) _removeItem(index);
                  },
                )
              : null,
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("AnimatedList Example"),
        actions: [
          TextButton(
            onPressed: _items.isNotEmpty ? _removeAll : null,
            child: Text("Clear list"),
          ),
        ],
      ),
      body: AnimatedList.separated(
        removedSeparatorBuilder: (context, index, animation) => SizedBox(),
        separatorBuilder: (context, index, animation) => SizedBox(),
        key: _listKey,
        initialItemCount: _items.length,
        itemBuilder: (context, index, animation) {
          return _buildItem(_items[index], animation);
        },
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
════════ Exception caught by gesture ═══════════════════════════════════════════
The following assertion was thrown while handling a gesture:
'package:flutter/src/widgets/animated_scroll_view.dart': Failed assertion: line 1398 pos 12: 'itemIndex >= 0 && itemIndex < _itemsCount': is not true.

Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=02_bug.yml

When the exception was thrown, this was the stack:
#2      _SliverAnimatedMultiBoxAdaptorState.removeItem (package:flutter/src/widgets/animated_scroll_view.dart:1398:12)
animated_scroll_view.dart:1398
#3      _AnimatedScrollViewState.removeItem (package:flutter/src/widgets/animated_scroll_view.dart:757:52)
animated_scroll_view.dart:757
#4      _AnimatedListExampleState._removeItem (package:ainotes_test/main.dart:30:28)
main.dart:30
#5      _AnimatedListExampleState._buildItem.<anonymous closure> (package:ainotes_test/main.dart:76:38)
main.dart:76
#6      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1204:21)
ink_well.dart:1204
#7      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:345:24)
recognizer.dart:345
#8      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:758:11)
tap.dart:758
#9      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:383:5)
tap.dart:383
#10     BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:353:7)
tap.dart:353
#11     GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:173:27)
arena.dart:173
#12     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:532:20)
binding.dart:532
#13     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:498:22)
binding.dart:498
#14     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:473:11)
binding.dart:473
#15     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:437:7)
binding.dart:437
#16     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:394:5)
binding.dart:394
#17     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:341:7)
binding.dart:341
#18     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:308:9)
binding.dart:308
#19     _invoke1 (dart:ui/hooks.dart:346:13)
hooks.dart:346
#20     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:467:7)
platform_dispatcher.dart:467
#21     _dispatchPointerDataPacket (dart:ui/hooks.dart:281:31)
hooks.dart:281
(elided 2 frames from class _AssertionError)

Handler: "onTap"
Recognizer: TapGestureRecognizer#5a07d
    debugOwner: GestureDetector
    state: ready
    won arena
    finalPosition: Offset(378.3, 718.0)
    finalLocalPosition: Offset(24.3, 25.4)
    button: 1
    sent tap down
════════════════════════════════════════════════════════════════════════════════

Flutter Doctor output

Doctor output
flutter doctor --verbose
[✓] Flutter (Channel stable, 3.35.7, on macOS 26.3 25D125
    darwin-arm64, locale en-US) [289ms]
    • Flutter version 3.35.7 on channel stable at
      /Users/ankozyrenko/fvm/versions/3.35.7
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision adc9010625 (7 months ago), 2025-10-21
      14:16:03 -0400
    • Engine revision 035316565a
    • Dart version 3.9.2
    • DevTools version 2.48.0
    • Feature flags: enable-web, enable-linux-desktop,
      enable-macos-desktop, enable-windows-desktop, enable-android,
      enable-ios, cli-animations, enable-lldb-debugging

[✓] Android toolchain - develop for Android devices (Android SDK
    version 35.0.0) [1,072ms]
    • Android SDK at /Users/ankozyrenko/Library/Android/sdk
    • Emulator version 36.2.12.0 (build_id 14214601) (CL:N/A)
    • Platform android-36, build-tools 35.0.0
    • ANDROID_HOME = /Users/ankozyrenko/Library/Android/sdk
    • ANDROID_SDK_ROOT = /Users/ankozyrenko/Library/Android/sdk
    • Java binary at:
      /Library/Java/JavaVirtualMachines/jdk-19.jdk/Contents/Home/bin/j
      ava
      This JDK is specified in your Flutter configuration.
      To change the current JDK, run: `flutter config
      --jdk-dir="path/to/jdk"`.
    • Java version Java(TM) SE Runtime Environment (build 19.0.2+7-44)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 26.1) [875ms]
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 17B55
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web [6ms]
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google
      Chrome

[✓] Android Studio (version 2025.1) [5ms]
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build
      21.0.8+-14018985-b1038.68)

[✓] VS Code (version 1.115.0) [4ms]
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.134.0

[✓] Connected device (3 available) [6.3s]
    • iPhone 16 Plus (mobile) • 7D6C5B0C-3EEE-4EBD-B239-BB2D7ED95DF2 •
      ios            • com.apple.CoreSimulator.SimRuntime.iOS-18-1
      (simulator)
    • macOS (desktop)         • macos                                •
      darwin-arm64   • macOS 26.3 25D125 darwin-arm64
    • Chrome (web)            • chrome                               •
      web-javascript • Google Chrome 147.0.7727.55
    ! Error: Browsing on the local area network for iPhone Ян
      Козыренко. Ensure the device is unlocked and attached with a
      cable or associated with the same local area network as this
      Mac.
      The device must be opted into Developer Mode to connect
      wirelessly. (code -27)

[✓] Network resources [460ms]
    • All expected network resources are available.

• No issues found!

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work listc: crashStack traces logged to the consoleframeworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onteam-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework teamwaiting for PR to land (fixed)A fix is in flight

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions