[CarouselView] Crash (RangeError / ArgumentError) when children or itemCount is empty with infinite: true or CarouselController.animateToItem

オープン 初心者向け
#195,878 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@assassinaj602 がすでに取り組んでいます。

2026年11月3日 から。

  • #195886 @assassinaj602 による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
62/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
dart
領域
mobile

調査の方向性

クラッシュは packages/flutter/lib/src/material/carousel.dart で発生しています。具体的には _CarouselViewState._buildSliverCarousel の childCount 式(infinite が null を強制する部分)と、CarouselController.animateToItem および _getTargetOffset の index.clamp(0, itemCount - 1) のロジックです。まず issue にある children が空のスニペットで再現させ、そのうえで空のケースをガードしてください。完了条件は、空の無限カルーセルが例外なく描画されること、itemCount が 0 のとき itemBuilder が呼ばれないこと、そして animateToItem(0) が何もしないことです。

索引モデルが issue の本文から書いたものです。

説明

p: material_ui package platform-android platform-ios platform-linux platform-macos platform-web team-design
Steps to reproduce
  1. Create a CarouselView or CarouselView.weighted with infinite: true and an empty list of children: children: const <Widget>[].
  2. Run the application. Notice it immediately throws an unhandled RangeError (length): Invalid value: Valid value range is empty: 0 during layout when constructing item 0.
  3. Alternatively, create a CarouselView.builder with infinite: true and itemCount: 0. Notice the builder is invoked with indices 0, 1, 2, 3... despite itemCount == 0.
  4. Alternatively, create a CarouselView with a CarouselController and an empty list of children (or itemCount: 0), and call controller.animateToItem(0). Notice it throws an unhandled ArgumentError: 'lowerLimit' (0) cannot be greater than 'upperLimit' (-1).
Expected results
  1. When infinite: true and children.isEmpty (or itemCount == 0), CarouselView / CarouselView.weighted / CarouselView.builder should render an empty scrollable viewport without throwing exceptions (matching the behavior when infinite: false).
  2. CarouselView.builder should not invoke itemBuilder when itemCount == 0.
  3. CarouselController.animateToItem should safely early-return or no-op when there are no items to animate to, rather than throwing an ArgumentError from index.clamp(0, itemCount - 1).
Actual results
  1. For CarouselView and CarouselView.weighted with infinite: true and children: const <Widget>[]:

    ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
    The following RangeError was thrown building:
    RangeError (length): Invalid value: Valid value range is empty: 0
    
    When the exception was thrown, this was the stack:
    #0      _Array.[] (dart:core-patch/array.dart)
    #1      _CarouselViewState._buildCarouselItem (package:flutter/src/material/carousel.dart:635:38)
    #2      _CarouselViewState._buildSliverCarousel.<anonymous closure> (package:flutter/src/material/carousel.dart:686:63)
    #3      SliverChildBuilderDelegate.build (package:flutter/src/widgets/scroll_delegate.dart:553:22)
    #4      SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:1061:28)
    
  2. For CarouselView.builder with infinite: true and itemCount: 0:
    itemBuilder is called with indices 0, 1, 2, 3...

  3. For CarouselController.animateToItem(0) on an empty CarouselView:

    ArgumentError: 'lowerLimit' (0) cannot be greater than 'upperLimit' (-1)
    package:flutter/src/material/carousel.dart:1972:25: CarouselController.animateToItem
    
Root Cause

In packages/flutter/lib/src/material/carousel.dart:

  1. In _CarouselViewState._buildSliverCarousel:

    final int? childCount = widget.infinite
        ? null
        : widget.itemBuilder != null
        ? widget.itemCount
        : widget.children.length;
    

    When widget.infinite is true, childCount is unconditionally set to null even if children.isEmpty or itemCount == 0. As a result, the sliver delegate builds child index 0:

    Widget contents = widget.children[index];
    

    which throws RangeError (length) because widget.children is empty.
    Additionally, in builder mode, childCount: null causes itemBuilder to be invoked indefinitely even though itemCount == 0.

  2. In CarouselController.animateToItem (and _getTargetOffset):

    if (_carouselState!.widget.itemBuilder != null) {
      final int? itemCount = _carouselState!.widget.itemCount;
      index = itemCount != null ? index.clamp(0, itemCount - 1) : 0;
    } else {
      index = index.clamp(0, _carouselState!.widget.children.length - 1);
    }
    

    When itemCount == 0 or children.length == 0, itemCount - 1 evaluates to -1, leading to index.clamp(0, -1), which throws ArgumentError: 'lowerLimit' (0) cannot be greater than 'upperLimit' (-1).

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

void main() {
  runApp(const MaterialApp(home: CarouselEmptyRepro()));
}

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

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: SizedBox(
          height: 200,
          child: CarouselView(
            itemExtent: 200.0,
            infinite: true,
            children: <Widget>[], // Throws RangeError (length): Invalid value: Valid value range is empty: 0
          ),
        ),
      ),
    );
  }
}
Screenshots or Video

N/A

Logs
Logs
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following RangeError was thrown building:
RangeError (length): Invalid value: Valid value range is empty: 0

When the exception was thrown, this was the stack:
#0      _Array.[] (dart:core-patch/array.dart)
#1      _CarouselViewState._buildCarouselItem (package:flutter/src/material/carousel.dart:635:38)
#2      _CarouselViewState._buildSliverCarousel.<anonymous closure> (package:flutter/src/material/carousel.dart:686:63)
#3      SliverChildBuilderDelegate.build (package:flutter/src/widgets/scroll_delegate.dart:553:22)
#4      SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:1061:28)
#5      SliverMultiBoxAdaptorElement.createChild.<anonymous closure> (package:flutter/src/widgets/sliver.dart:1077:55)
#6      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:3121:19)
#7      SliverMultiBoxAdaptorElement.createChild (package:flutter/src/widgets/sliver.dart:1067:12)
#8      RenderSliverMultiBoxAdaptor._createOrObtainChild.<anonymous closure> (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:367:23)
#9      RenderObject.invokeLayoutCallback.<anonymous closure> (package:flutter/src/rendering/object.dart:3049:17)
#10     PipelineOwner._enableMutationsToDirtySubtrees (package:flutter/src/rendering/object.dart:1225:15)
#11     RenderObject.invokeLayoutCallback (package:flutter/src/rendering/object.dart:3048:14)
#12     RenderSliverMultiBoxAdaptor._createOrObtainChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:356:5)
#13     RenderSliverMultiBoxAdaptor.addInitialChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:454:5)
#14     RenderSliverFixedExtentBoxAdaptor.performLayout (package:flutter/src/rendering/sliver_fixed_extent_list.dart:369:12)
Flutter Doctor output
Doctor output
[✓] Flutter (Channel master, 3.51.0-1.0.pre-38, on Fedora Linux 45 (KDE Plasma Desktop Edition Prerelease) 7.2.9-300.fc45.x86_64, locale en_US.UTF-8)
    • Flutter version 3.51.0-1.0.pre-38 on channel master at /home/assassinaj602/Projects/New folder (4)/github_pr/flutter
    • Framework revision f7b47b2188 (3 hours ago), 2026-11-03 05:13:25 +0000
    • Engine revision f7b47b2188
    • Dart version 3.15.0 (build 3.15.0-101.0.dev)
    • DevTools version 2.62.0-dev.0

[✓] Android toolchain - develop for Android devices (Android SDK version 36.0.0)
    • Android SDK at /home/assassinaj602/Android/Sdk
    • Emulator version 37.1.11.0 (build_id 15917651) (CL:N/A)
    • Platform android-36, build-tools 36.0.0

[✓] Chrome - develop for the web
    • Chrome at google-chrome

[✓] Linux toolchain - develop for Linux desktop
    • clang version 23.1.2 (Fedora 23.1.2-2.fc45)
    • cmake version 4.3.0
    • ninja version 1.13.2
    • pkg-config version 2.5.1

[✓] Connected device (2 available)
    • Linux (desktop) • linux  • linux-x64      • Fedora Linux 45 (KDE Plasma Desktop Edition Prerelease) 7.2.9-300.fc45.x86_64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 154.0.8037.97

[✓] Network resources
    • All expected network resources are available.
主要言語
Dart
スター
181k
フォーク
33.3k
平均マージ
1日 22時間
マージ済み PR(30日)
280

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

flutter/flutter のほかの issue

flutter/flutter の issue をすべて見る

似ている issue

Dart の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。