Sitelet https://github.com/flutter/flutter/issues/190800
Skip to content

[two_dimensional_scrollables] TableView throws "The paint extent of the child has not been determined yet" while scrolling with trailing pinned rows/columns enabled #190800

Description

@xianjie-li

Steps to reproduce

  1. Create a TableView.builder with trailingPinnedRowCount and/or trailingPinnedColumnCount greater than 0, and enough rows/columns so the table is scrollable in both directions.
  2. Open the app and continuously scroll horizontally to the right (scrolling to the middle first makes it easier to hit).
  3. The paint assertion below fires reliably within a few seconds.

Expected results

Scrolling a table with trailing pinned rows/columns should re-layout smoothly without throwing any exceptions.

Actual results

While scrolling horizontally, the following paint assertion is thrown:

════════ Exception caught by rendering library ═════════════════════════════════
The paint extent of the child has not been determined yet.
The relevant error-causing widget was:
    TableView TableView:...
════════════════════════════════════════════════════════════════════════════════

The render tree right before the error contains stale cells whose layoutOffset is set but paintOffset is null and are marked not visible / never painted:

    (row: 46, column: 27): RenderRepaintBoundary#1decd NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
        needs compositing
        parentData: vicinity=(row: 46, column: 27); layoutOffset=Offset(640.5, 472.0); paintOffset=null; not visible;
        constraints: BoxConstraints(w=100.0, h=32.0)
        size: Size(100.0, 32.0)
        usefulness ratio: no metrics collected yet (never painted)
        ...

Code sample

Code sample

Reproduction hint: press "Auto scroll right" — the assertion fires within a few seconds.

// Temporary repro file: two_dimensional_scrollables trailing pinned layout bug
//
// Reliable repro: open the app and keep scrolling right (or press
// "Auto scroll right"); the paint assertion fires within seconds:
//   "The paint extent of the child has not been determined yet."
//
// The render tree right before the error shows stale cells with layoutOffset
// set but paintOffset=null and marked "not visible", meaning layout and paint
// get out of sync while scrolling with trailing pinned rows/columns enabled.
//
// Run: flutter run -t example/repro_bug.dart -d macos
import "dart:async";

import "package:flutter/material.dart";
import "package:two_dimensional_scrollables/two_dimensional_scrollables.dart";

void main() => runApp(const MaterialApp(home: Demo()));

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

  @override
  State<Demo> createState() => _DemoState();
}

class _DemoState extends State<Demo> {
  // Horizontal/vertical scroll controllers (start scrolled to the middle,
  // which makes the bug easier to hit).
  final ScrollController _h = ScrollController(initialScrollOffset: 1000);
  final ScrollController _v = ScrollController(initialScrollOffset: 1000);

  // Auto-scroll timer that keeps scrolling right to trigger the bug.
  Timer? _autoTimer;
  bool _autoScrolling = false;

  @override
  void dispose() {
    _autoTimer?.cancel();
    _h.dispose();
    _v.dispose();
    super.dispose();
  }

  /// Start/stop continuous auto-scroll to the right.
  void _toggleAutoScroll() {
    if (_autoScrolling) {
      _autoTimer?.cancel();
      setState(() => _autoScrolling = false);
      return;
    }
    setState(() => _autoScrolling = true);
    // Scroll 5px per frame; jump back to the start when reaching the end.
    _autoTimer = Timer.periodic(const Duration(milliseconds: 16), (_) {
      if (!_h.hasClients) return;
      final max = _h.position.maxScrollExtent;
      final target = _h.offset + 5;
      _h.jumpTo(target > max ? 0 : target);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("trailing pinned scroll repro")),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(16),
            child: FilledButton(
              onPressed: _toggleAutoScroll,
              child: Text(_autoScrolling ? "Stop auto scroll" : "Auto scroll right"),
            ),
          ),
          Expanded(
            child: Center(
              child: SizedBox(
                width: 600,
                height: 400,
                child: TableView.builder(
                  verticalDetails: ScrollableDetails.vertical(controller: _v),
                  horizontalDetails:
                      ScrollableDetails.horizontal(controller: _h),
                  columnCount: 30,
                  rowCount: 100,
                  pinnedColumnCount: 1,
                  trailingPinnedColumnCount: 2,
                  trailingPinnedRowCount: 1,
                  columnBuilder: (index) => const TableSpan(
                    extent: FixedTableSpanExtent(100),
                  ),
                  rowBuilder: (index) => const TableSpan(
                    extent: FixedTableSpanExtent(32),
                  ),
                  cellBuilder: (context, vicinity) => TableViewCell(
                    child: Center(
                      child: Text("${vicinity.row},${vicinity.column}"),
                    ),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.44.6, on macOS 26.5.2 25F84 darwin-arm64, locale zh-Hans-CN) [639ms]
    • Flutter version 3.44.6 on channel stable at /Users/lixianjie/code/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ee80f08bbf (4 weeks ago), 2026-07-08 15:02:06 -0700
    • Engine revision 83675ed276
    • Dart version 3.12.2
    • DevTools version 2.57.0
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn
    • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop,
      enable-android, enable-ios, cli-animations, enable-native-assets, enable-swift-package-manager,
      omit-legacy-version-file, enable-lldb-debugging, enable-uiscene-migration

[✓] Android toolchain - develop for Android devices (Android SDK version 36.0.0) [4.2s]
    • Android SDK at /Users/lixianjie/Library/Android/sdk
    • Emulator version 36.6.11.0 (build_id 15507667) (CL:N/A)
    • Platform android-36, build-tools 36.0.0
    • Java binary at: /Users/lixianjie/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
      This is the JDK bundled with the latest Android Studio installation on this machine.
      To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment (build 21.0.6+-13355223-b631.42)
    • All Android licenses accepted.

[!] Xcode - develop for iOS and macOS (Xcode 26.6) [2.2s]
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 17F113
    ! CocoaPods 1.15.2 out of date (1.16.2 is recommended).
        CocoaPods is a package manager for iOS or macOS platform code.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/to/platform-plugins
      To update CocoaPods, see https://guides.cocoapods.org/using/getting-started.html#updating-cocoapods

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

[✓] Connected device (2 available) [6.6s]
    • macOS (desktop) • macos  • darwin-arm64   • macOS 26.5.2 25F84 darwin-arm64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 151.0.7922.76
    ! Error: Browsing on the local area network for 李显杰的iPad. 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 [3.5s]
    • All expected network resources are available.

! Doctor found issues in 1 category.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: crashStack traces logged to the consolef: scrollingViewports, list views, slivers, etc.p: two_dimensional_scrollablesIssues pertaining to the two_dimensional_scrollables packagepackageflutter/packages repository. See also p: labels.team-ecosystemOwned by Ecosystem teamtriaged-ecosystemTriaged by Ecosystem team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions