Skip to content

Regression “Null check operator used on a null value” thrown by LayoutBuilder #168936

@b3nni97

Description

@b3nni97

Steps to reproduce

  1. Run the minimal reproducible sample on the current master channel.
  2. Wait ~1 – 2 s – the app crashes with the error
    "Null check operator used on a null value" coming from LayoutBuilder.

Expected results

The sample should run without errors.

Actual results

"Null check operator used on a null value” exceptions are thrown permanently.

Regression details:
First bad commit: merge of PR #154681 – “Make sure LayoutBuilder rebuild in an inactive route” (28 Mar 2025).
git bisect confirms that the crash is introduced by this PR.
@LongCatIsLooong

Code sample

Code sample

I rebuilt the key parts of our app’s complex widget hierarchy in this sample; the structure is deliberate, because simpler layouts don’t trigger the bug.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(
    CupertinoApp(
      home: CupertinoPageScaffold(
        navigationBar: CupertinoNavigationBar(
          middle: Text('LayoutBuilder issue'),
        ),
        child: TestWidget(),
      ),
    ),
  );
}

class TestWidget extends StatefulWidget {
  @override
  State<TestWidget> createState() => _TestWidgetState();
}

class _TestWidgetState extends State<TestWidget>
    with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
  late final AnimationController _controller;
  late final Animation<double> _height;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    );

    _height = Tween<double>(
      begin: 0.1,
      end: 0.5,
    ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeInOut));

    _controller.repeat(reverse: true);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);

    return AnimatedBuilder(
      animation: _height,
      builder: (context, child) {
        return FractionallySizedBox(
          heightFactor: _height.value,
          child: CustomScrollView(
            slivers: [
              SliverList(
                delegate: SliverChildListDelegate([TestChild(), TestChild()]),
              ),
            ],
          ),
        );
      },
    );
  }

  @override
  bool get wantKeepAlive => true;
}

class TestChild extends StatefulWidget {
  @override
  State<TestChild> createState() => _TestChildState();
}

class _TestChildState extends State<TestChild>
    with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Column(
      children: [
        Container(
          height: 500,
          child: LayoutBuilder(
            builder: (context, constraints) {
              return Container(color: Colors.red, width: double.infinity);
            },
          ),
        ),
      ],
    );
  }
}

Screenshots or Video

Logs

Logs
════════ Exception caught by rendering library ═════════════════════════════════
The following _TypeError was thrown during performLayout():
Null check operator used on a null value

The relevant error-causing widget was:
    LayoutBuilder LayoutBuilder:file:///Users/xxx/Desktop/layout_builder_issue/lib/main.dart:91:18

When the exception was thrown, this was the stack:
#0      RenderObject.layout (package:flutter/src/rendering/object.dart:2716:96)
object.dart:2716
#1      _RenderLayoutBuilder.performLayout (package:flutter/src/widgets/layout_builder.dart:440:14)
layout_builder.dart:440
#2      RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:2627:7)
object.dart:2627
#3      PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1145:18)
object.dart:1145
#4      PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1158:15)
object.dart:1158
#5      RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:629:23)
binding.dart:629
#6      WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:1231:13)
binding.dart:1231
#7      RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:495:5)
binding.dart:495
#8      SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1438:15)
binding.dart:1438
#9      SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1351:9)
binding.dart:1351
#10     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1204:5)
binding.dart:1204
#11     _invoke (dart:ui/hooks.dart:331:13)
hooks.dart:331
#12     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:444:5)
platform_dispatcher.dart:444
#13     _drawFrame (dart:ui/hooks.dart:303:31)
hooks.dart:303

The following RenderObject was being processed when the exception was fired: _RenderLayoutBuilder#c6cb0 NEEDS-LAYOUT NEEDS-PAINT
    parentData: <none> (can use size)
    constraints: BoxConstraints(0.0<=w<=440.0, h=500.0)
    size: Size(440.0, 500.0)
    child: RenderConstrainedBox#52f91 NEEDS-PAINT
        parentData: offset=Offset(0.0, 0.0) (can use size)
        constraints: BoxConstraints(0.0<=w<=440.0, h=500.0)
        size: Size(440.0, 500.0)
        additionalConstraints: BoxConstraints(w=Infinity, 0.0<=h<=Infinity)
        child: _RenderColoredBox#6bdaa NEEDS-PAINT
            parentData: <none> (can use size)
            constraints: BoxConstraints(w=440.0, h=500.0)
            size: Size(440.0, 500.0)
            behavior: opaque
            child: RenderLimitedBox#6da64 NEEDS-PAINT
                parentData: <none> (can use size)
                constraints: BoxConstraints(w=440.0, h=500.0)
                size: Size(440.0, 500.0)
                maxWidth: 0.0
                maxHeight: 0.0
                child: RenderConstrainedBox#e6ea7 NEEDS-PAINT
                    parentData: <none> (can use size)
                    constraints: BoxConstraints(w=440.0, h=500.0)
                    size: Size(440.0, 500.0)
                    additionalConstraints: BoxConstraints(biggest)
RenderObject: _RenderLayoutBuilder#c6cb0 NEEDS-LAYOUT NEEDS-PAINT
    parentData: <none> (can use size)
    constraints: BoxConstraints(0.0<=w<=440.0, h=500.0)
    size: Size(440.0, 500.0)
    child: RenderConstrainedBox#52f91 NEEDS-PAINT
        parentData: offset=Offset(0.0, 0.0) (can use size)
        constraints: BoxConstraints(0.0<=w<=440.0, h=500.0)
        size: Size(440.0, 500.0)
        additionalConstraints: BoxConstraints(w=Infinity, 0.0<=h<=Infinity)
        child: _RenderColoredBox#6bdaa NEEDS-PAINT
            parentData: <none> (can use size)
            constraints: BoxConstraints(w=440.0, h=500.0)
            size: Size(440.0, 500.0)
            behavior: opaque
            child: RenderLimitedBox#6da64 NEEDS-PAINT
                parentData: <none> (can use size)
                constraints: BoxConstraints(w=440.0, h=500.0)
                size: Size(440.0, 500.0)
                maxWidth: 0.0
                maxHeight: 0.0
                child: RenderConstrainedBox#e6ea7 NEEDS-PAINT
                    parentData: <none> (can use size)
                    constraints: BoxConstraints(w=440.0, h=500.0)
                    size: Size(440.0, 500.0)
                    additionalConstraints: BoxConstraints(biggest)

Flutter Doctor output

Doctor output
Flutter 3.33.0-1.0.pre.78 • channel master • https://github.com/flutter/flutter.git
Framework • revision 773d076621 (21 hours ago) • 2025-05-14 15:59:14 -0700
Engine • revision 773d076621 (21 hours ago) • 2025-05-14 15:59:14 -0700
Tools • Dart 3.9.0 (build 3.9.0-117.0.dev) • DevTools 2.46.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: error messageError messages from the Flutter frameworkc: regressionIt was better in the past than it is nowcustomer: googleVarious Google teamsfound in release: 3.32Found to occur in 3.32found in release: 3.33Found to occur in 3.33frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionteam-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions