Skip to content

Failed assertion in widgets library apparently caused by tooltip: RenderBox was not laid out #169126

Closed
@zetches

Description

@zetches

Hi. I have encountered a failed assertion error, and the error message asked me to file a bug report. I searched around a bit but couldn't find an obvious duplicate, hence this issue. (Edit: on some more searching, it may be a duplicate of #167722 ?)

════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building Builder(dirty):
RenderBox was not laid out: RenderFractionalTranslation#167c0 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 2251 pos 12: 'hasSize'

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=2_bug.yml

The relevant error-causing widget was:
    IconButton IconButton:file:///Users/zetches/Documents/test_flutter/my_flutter_app/lib/main.dart:47:36

When the exception was thrown, this was the stack:
#2      RenderBox.size (package:flutter/src/rendering/box.dart:2251:12)
box.dart:2251
#3      RenderFractionalTranslation.applyPaintTransform (package:flutter/src/rendering/proxy_box.dart:2974:42)
proxy_box.dart:2974
#4      RenderObject.getTransformTo (package:flutter/src/rendering/object.dart:3520:25)
object.dart:3520
#5      RenderBox.localToGlobal (package:flutter/src/rendering/box.dart:3082:39)
box.dart:3082
#6      TooltipState._buildTooltipOverlay (package:flutter/src/material/tooltip.dart:793:31)
tooltip.dart:793
#7      Builder.build (package:flutter/src/widgets/basic.dart:7818:48)
basic.dart:7818
#8      StatelessElement.build (package:flutter/src/widgets/framework.dart:5799:49)
framework.dart:5799
#9      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5733:15)
framework.dart:5733
#10     Element.rebuild (package:flutter/src/widgets/framework.dart:5445:7)
framework.dart:5445
#11     StatelessElement.update (package:flutter/src/widgets/framework.dart:5805:5)
framework.dart:5805
#12     Element.updateChild (package:flutter/src/widgets/framework.dart:3998:15)
framework.dart:3998
#13     SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:7034:14)
framework.dart:7034
#14     Element.updateChild (package:flutter/src/widgets/framework.dart:3998:15)

Here's some minimal code that will reproduce it on my setup quite consistently:

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) => MaterialApp(
        title: 'Dialog push bug',
        home: const HomePage(),
      );
}

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

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(title: const Text('Home')),
        body: Center(
          child: ElevatedButton(
            onPressed: () => _openPicker(context),
            child: const Text('Open picker'),
          ),
        ),
      );

  void _openPicker(BuildContext context) {
    showDialog(
      context: context,
      builder: (ctx) {
        String? selected = 'a';
        return StatefulBuilder(
          builder: (ctx, setState) => AlertDialog(
            title: const Text('Choose library'),
            content: ListTileTheme(
              dense: true,
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  RadioListTile<String>(
                    value: 'a',
                    groupValue: selected,
                    title: const Text('Custom list A'),
                    onChanged: (v) => setState(() => selected = v),
                    secondary: IconButton(
                      icon: const Icon(Icons.edit),
                      tooltip: 'Edit', // NOTE: removing this line seems to fix it
                      onPressed: () {
                        Navigator.pop(ctx);         
                        Navigator.push(ctx, MaterialPageRoute(
                          builder: (_) => const DummyPage(),
                        ));                             
                      },
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      },
    );
  }
}

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

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(title: const Text('Edit page')),
        body: const Center(child: Text('Hello')),
      );
}

To reproduce, run the above code, tap “Open picker”, and in the dialog, click or double-click the pencil icon next to the only list item. The assertion error is thrown relatively often when the icon is single-clicked. It happens almost every time if you double-click the icon.

I worked around it by removing the tooltip (as I noticed the occurrence of "tooltip" in the stack trace, so figured that might have something to do with it). That appears to fix it, so it is not blocking me.

flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.29.2, on macOS 15.4.1 24E263 darwin-arm64, locale en-US)
(...)

Hope this helps!

Metadata

Metadata

Assignees

No one assigned

    Labels

    r: fixedIssue is closed as already fixed in a newer version

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy