Repository navigation
Closed
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work lista: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)Accessibility, e.g. VoiceOver or TalkBack. (aka a11y)team-accessibilityOwned by Framework Accessibility team (i.e. responsible for accessibility code in flutter/flutter)Owned by Framework Accessibility team (i.e. responsible for accessibility code in flutter/flutter)triaged-accessibilityTriaged by Framework Accessibility teamTriaged by Framework Accessibility team
Description
Steps to reproduce
- run sample code;
- hover mouse pointer on "bad text" until "bad tooltip" shows;
- move mouse pointer out of "bad text" so that "bad tooltip" disappears;
- hover mouse pointer on "bad text" again until "bad tooltip" shows;
- move mouse pointer out of "bad text";
Expected results
at step 5, "bad tooltip" disappears;
Actual results
at step 5, asserts with:
_AssertionError ('package:flutter/src/semantics/semantics.dart': Failed assertion: line 3013 pos 16: '!child.attached': is not true.)
with stack like:
_AssertionError._doThrowNew (/DATA1/FLUTTER_SDK/flutter.latest/bin/cache/pkg/sky_engine/lib/_internal/vm/lib/errors_patch.dart:67)
_AssertionError._throwNew (/DATA1/FLUTTER_SDK/flutter.latest/bin/cache/pkg/sky_engine/lib/_internal/vm/lib/errors_patch.dart:49)
SemanticsNode._replaceChildren (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/semantics/semantics.dart:3013)
SemanticsNode.updateWith (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/semantics/semantics.dart:3779)
_RenderObjectSemantics._buildSemanticsSubtree (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6258)
_RenderObjectSemantics._produceSemanticsNode (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6272)
_RenderObjectSemantics._buildSemantics (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6205)
_RenderObjectSemantics._buildSemanticsSubtree (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6241)
_RenderObjectSemantics._produceSemanticsNode (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6272)
_RenderObjectSemantics._buildSemantics (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6205)
_RenderObjectSemantics._buildSemanticsSubtree (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6241)
_RenderObjectSemantics._produceSemanticsNode (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6272)
_RenderObjectSemantics._buildSemantics (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6205)
_RenderObjectSemantics._buildSemanticsSubtree (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6241)
_RenderObjectSemantics._produceSemanticsNode (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6272)
_RenderObjectSemantics._buildSemantics (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6205)
_RenderObjectSemantics._buildSemanticsSubtree (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6241)
_RenderObjectSemantics.ensureSemanticsNode (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6177)
PipelineOwner.flushSemantics (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:1636)
PipelineOwner.flushSemantics (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:1653)
RendererBinding.drawFrame (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/binding.dart:650)
WidgetsBinding.drawFrame (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/widgets/binding.dart:1573)
RendererBinding._handlePersistentFrameCallback (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/binding.dart:509)
SchedulerBinding._invokeFrameCallback (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/scheduler/binding.dart:1430)
SchedulerBinding.handleDrawFrame (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/scheduler/binding.dart:1345)
SchedulerBinding._handleDrawFrame (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/scheduler/binding.dart:1198)
_invoke (/DATA1/FLUTTER_SDK/flutter.latest/bin/cache/pkg/sky_engine/lib/ui/hooks.dart:423)
PlatformDispatcher._drawFrame (/DATA1/FLUTTER_SDK/flutter.latest/bin/cache/pkg/sky_engine/lib/ui/platform_dispatcher.dart:447)
_drawFrame (/DATA1/FLUTTER_SDK/flutter.latest/bin/cache/pkg/sky_engine/lib/ui/hooks.dart:395)
(btw, the line-numbers do not match authentic SDK due to some debug code I've added, see attached. I'm sure those debug code do not cause the problem, ;)
I think a direct cause of the assert is this:
diff --git a/packages/flutter/lib/src/semantics/semantics.dart b/packages/flutter/lib/src/semantics/semantics.dart
index 27a82695a98..d46fd5250d1 100644
--- a/packages/flutter/lib/src/semantics/semantics.dart
+++ b/packages/flutter/lib/src/semantics/semantics.dart
@@ -3003,6 +3007,7 @@ class SemanticsNode with DiagnosticableTreeMixin {
// ancestors. In that case, we drop the child eagerly here.
// TODO(ianh): Find a way to assert that the same node didn't
// actually appear in the tree in two places.
+ // FIXME: child.parent?._children is **NOT UPDATED** !!!
child.parent?._dropChild(child);
}
assert(!child.attached);
Code sample
Code sample
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() => runApp(
const MaterialApp(
home: Scaffold(
body: TestWidget(),
),
),
);
class TestWidget extends StatelessWidget {
const TestWidget({super.key});
Widget decorate(Widget child) {
//return child;
return DecoratedBox(
decoration: BoxDecoration(border: Border.all()),
child: child,
);
}
@override
Widget build(BuildContext context) {
Widget goodTooltip = Tooltip(
message: 'good tooltip',
child: Semantics(
explicitChildNodes: true,
child: const Text('good text'),
),
);
// harmless tooltip;
Widget badTooltip = Tooltip(
message: 'bad tooltip',
child: Semantics(
explicitChildNodes: true,
child: const Text('bad text'),
),
);
// must, to enable SemanticsNode "stealing";
badTooltip = Overlay.wrap(child: ExcludeSemantics(child: badTooltip));
// must too, to disable certain SemanticsNode rebuilding;
badTooltip = SizedBox(width: 200, height: 100, child: badTooltip);
Widget widget = Column(
spacing: 20,
children: [
ExcludeSemantics(
child: SizedBox(
width: 200,
height: 60,
child: Center(
child: TextButton(
onPressed: () {
debugDumpSemanticsTree();
},
child: const Text('debugDumpSemanticsTree'),
),
),
),
),
decorate(goodTooltip),
decorate(badTooltip),
],
);
// this is also a must;
widget = Dialog(child: widget);
return widget;
}
}Logs
comments on log:
- SemanticsNode, n#4: 29f17e56, n#5: fdb5516, n#6: 3747acb0;
- regex: '21e214f0|f49ed51|c881c69'
- ln#71, debugDumpSemanticsTree, n#4 owns n#5;
- ln#98-129, show 'bad tooltip', n#4 owns n#6 owns n#5;
- right after n#6 "steals" n#5 from n#4, n#4 temporarily contains an invalid
ref to n#5 in its _children; - n#4._children is shortly overwritten in _replaceChildren;
- right after n#6 "steals" n#5 from n#4, n#4 temporarily contains an invalid
- ln#194-213, hide 'bad tooltip', n#4 owns n#5;
- n#4 "steals" n#5 back from n#6;
- n#6 is kept in related _RenderObjectSemantics.cacheSemanticsNode, and
contains an invalid ref to n#5 in its _children;
- ln#230-247, show 'bad tooltip' again;
- should be n#4 owns n#6 owns n#5;
- but for some reason (i can't explain), n#6 is not rebuilt;
- if n#6 is rebuilt, n#5 would be "stolen" from n#4 before n#4's _replaceChildren;
- without rebuild, n#5 is dropped in n#4's _replaceChildren (parent == null),
but still ref'ed in n#6's _children, and attached (recursively in n#6's attach);- this can be caught by the commented asserting 'XXX: catch bad parent' in
debug patch;
- this can be caught by the commented asserting 'XXX: catch bad parent' in
- ln#312, hide 'bad tooltip' again; assert because n#5 is attached but has no parent;
- ln#317, asserts;
Logs, with debug.semantics.patch applied
Launching /home/xiangh/flutter-arena/mysample/lib/main.dart on Linux in debug mode...
✓ Built build/linux/x64/debug/bundle/mysample
Gdk-Message: 09:27:42.972: Unable to load from the cursor theme
Connecting to VM Service at ws://127.0.0.1:40245/ijPFzu3mCK8=/ws
Connected to the VM Service.
2026-07-23 09:27:44.651757: attach, cf98f, SemanticsNode#0(Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible)
2026-07-23 09:27:44.678217: -------- _replaceChildren: fdb5516 --------
======== sawChange = false ========
2026-07-23 09:27:44.679673: -------- _replaceChildren: 29f17e56 --------
2026-07-23 09:27:44.680135: _adoptChild, 29f17e56 => fdb5516, SemanticsNode#4(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr, role: dialog) => SemanticsNode#5(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
stack: ...
#1 SemanticsNode._replaceChildren (package:flutter/src/semantics/semantics.dart:3097:6)
#2 SemanticsNode.updateWith (package:flutter/src/semantics/semantics.dart:3778:5)
#3 _RenderObjectSemantics._buildSemanticsSubtree (package:flutter/src/rendering/object.dart:6258:12)
#4 _RenderObjectSemantics._produceSemanticsNode (package:flutter/src/rendering/object.dart:6272:5)
...
new: fdb5516, SemanticsNode#5(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
======== sawChange = true ========
2026-07-23 09:27:44.687172: -------- _replaceChildren: 10889296 --------
2026-07-23 09:27:44.687275: _adoptChild, 10889296 => 29f17e56, SemanticsNode#3(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), flags: [scopesRoute]) => SemanticsNode#4(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr, role: dialog)
stack: ...
#1 SemanticsNode._replaceChildren (package:flutter/src/semantics/semantics.dart:3097:6)
#2 SemanticsNode.updateWith (package:flutter/src/semantics/semantics.dart:3778:5)
#3 _RenderObjectSemantics._buildSemanticsSubtree (package:flutter/src/rendering/object.dart:6258:12)
#4 _RenderObjectSemantics._produceSemanticsNode (package:flutter/src/rendering/object.dart:6272:5)
...
new: 29f17e56, SemanticsNode#4(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr, role: dialog)
======== sawChange = true ========
2026-07-23 09:27:44.697656: -------- _replaceChildren: 190eb487 --------
2026-07-23 09:27:44.697756: _adoptChild, 190eb487 => 10889296, SemanticsNode#2(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), sortKey: OrdinalSortKey#ee3e8(order: 0.0)) => SemanticsNode#3(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), flags: [scopesRoute])
stack: ...
#1 SemanticsNode._replaceChildren (package:flutter/src/semantics/semantics.dart:3097:6)
#2 SemanticsNode.updateWith (package:flutter/src/semantics/semantics.dart:3778:5)
#3 _RenderObjectSemantics._buildSemanticsSubtree (package:flutter/src/rendering/object.dart:6258:12)
#4 _RenderObjectSemantics._produceSemanticsNode (package:flutter/src/rendering/object.dart:6272:5)
...
new: 10889296, SemanticsNode#3(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), flags: [scopesRoute])
======== sawChange = true ========
2026-07-23 09:27:44.700380: -------- _replaceChildren: 211e9bc0 --------
2026-07-23 09:27:44.700480: _adoptChild, 211e9bc0 => 190eb487, SemanticsNode#1(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), textDirection: ltr) => SemanticsNode#2(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), sortKey: OrdinalSortKey#ee3e8(order: 0.0))
stack: ...
#1 SemanticsNode._replaceChildren (package:flutter/src/semantics/semantics.dart:3097:6)
#2 SemanticsNode.updateWith (package:flutter/src/semantics/semantics.dart:3778:5)
#3 _RenderObjectSemantics._buildSemanticsSubtree (package:flutter/src/rendering/object.dart:6258:12)
#4 _RenderObjectSemantics._produceSemanticsNode (package:flutter/src/rendering/object.dart:6272:5)
...
new: 190eb487, SemanticsNode#2(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), sortKey: OrdinalSortKey#ee3e8(order: 0.0))
======== sawChange = true ========
2026-07-23 09:27:44.702308: -------- _replaceChildren: cf98f --------
2026-07-23 09:27:44.702387: _adoptChild, cf98f => 211e9bc0, SemanticsNode#0(dirty, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0)) => SemanticsNode#1(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), textDirection: ltr)
2026-07-23 09:27:44.703029: attach, 211e9bc0, SemanticsNode#1(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), textDirection: ltr)
2026-07-23 09:27:44.703475: attach, 190eb487, SemanticsNode#2(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), sortKey: OrdinalSortKey#ee3e8(order: 0.0))
2026-07-23 09:27:44.703957: attach, 10889296, SemanticsNode#3(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), flags: [scopesRoute])
2026-07-23 09:27:44.704403: attach, 29f17e56, SemanticsNode#4(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr, role: dialog)
2026-07-23 09:27:44.704857: attach, fdb5516, SemanticsNode#5(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
stack: ...
#1 SemanticsNode._replaceChildren (package:flutter/src/semantics/semantics.dart:3097:6)
#2 SemanticsNode.updateWith (package:flutter/src/semantics/semantics.dart:3778:5)
#3 _RenderObjectSemantics._buildSemanticsSubtree (package:flutter/src/rendering/object.dart:6258:12)
#4 _RenderObjectSemantics._produceSemanticsNode (package:flutter/src/rendering/object.dart:6272:5)
...
new: 211e9bc0, SemanticsNode#1(dirty, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), textDirection: ltr)
======== sawChange = true ========
SemanticsNode#0
│ Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0)
│
└─SemanticsNode#1
│ Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0)
│ textDirection: ltr
│
└─SemanticsNode#2
│ Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0)
│ sortKey: OrdinalSortKey#ee3e8(order: 0.0)
│
└─SemanticsNode#3
│ Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0)
│ flags: scopesRoute
│
└─SemanticsNode#4
│ Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0)
│ traversalParentIdentifier: _OverlayPortalState#18de2
│ tooltip: "good tooltip"
│ textDirection: ltr
│ role: dialog
│
└─SemanticsNode#5
Rect.fromLTRB(609.4, 104.0, 670.6, 124.0)
label: "good text"
textDirection: ltr
2026-07-23 09:27:50.638582: -------- _replaceChildren: 3747acb0 --------
2026-07-23 09:27:50.638816: _dropChild, 29f17e56 => fdb5516, SemanticsNode#4(Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr, role: dialog) => SemanticsNode#5(Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
2026-07-23 09:27:50.639950: dettach, fdb5516, SemanticsNode#5(Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
2026-07-23 09:27:50.640583: _adoptChild, 3747acb0 => fdb5516, SemanticsNode#6(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr) => SemanticsNode#5(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
stack: ...
#1 SemanticsNode._replaceChildren (package:flutter/src/semantics/semantics.dart:3097:6)
#2 SemanticsNode.updateWith (package:flutter/src/semantics/semantics.dart:3778:5)
#3 _RenderObjectSemantics._buildSemanticsSubtree (package:flutter/src/rendering/object.dart:6258:12)
#4 _RenderObjectSemantics._produceSemanticsNode (package:flutter/src/rendering/object.dart:6272:5)
...
new: fdb5516, SemanticsNode#5(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
======== sawChange = true ========
2026-07-23 09:27:50.642597: -------- _replaceChildren: 37dd4e97 --------
======== sawChange = false ========
2026-07-23 09:27:50.642837: -------- _replaceChildren: 29f17e56 --------
2026-07-23 09:27:50.643029: _adoptChild, 29f17e56 => 3747acb0, SemanticsNode#4(dirty, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), role: dialog) => SemanticsNode#6(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr)
2026-07-23 09:27:50.644005: attach, 3747acb0, SemanticsNode#6(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr)
2026-07-23 09:27:50.644531: attach, fdb5516, SemanticsNode#5(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
2026-07-23 09:27:50.644896: _adoptChild, 29f17e56 => 37dd4e97, SemanticsNode#4(dirty, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), role: dialog) => SemanticsNode#7(STALE, owner: null, Rect.fromLTRB(540.0, 144.0, 740.0, 244.0), traversalChildIdentifier: _OverlayPortalState#7e590)
2026-07-23 09:27:50.645560: attach, 37dd4e97, SemanticsNode#7(STALE, owner: null, Rect.fromLTRB(540.0, 144.0, 740.0, 244.0), traversalChildIdentifier: _OverlayPortalState#7e590)
stack: ...
#1 SemanticsNode._replaceChildren (package:flutter/src/semantics/semantics.dart:3097:6)
#2 SemanticsNode.updateWith (package:flutter/src/semantics/semantics.dart:3778:5)
#3 _RenderObjectSemantics._buildSemanticsSubtree (package:flutter/src/rendering/object.dart:6258:12)
#4 _RenderObjectSemantics._produceSemanticsNode (package:flutter/src/rendering/object.dart:6272:5)
...
old: fdb5516, SemanticsNode#5(dirty, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
new: 3747acb0, SemanticsNode#6(dirty, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr)
new: 37dd4e97, SemanticsNode#7(dirty, Rect.fromLTRB(540.0, 144.0, 740.0, 244.0), traversalChildIdentifier: _OverlayPortalState#7e590)
======== sawChange = true ========
2026-07-23 09:27:50.649374: -------- _replaceChildren: 10889296 --------
======== sawChange = false ========
2026-07-23 09:27:50.649696: -------- _replaceChildren: 190eb487 --------
======== sawChange = false ========
2026-07-23 09:27:50.649930: -------- _replaceChildren: 211e9bc0 --------
======== sawChange = false ========
2026-07-23 09:27:50.650115: -------- _replaceChildren: cf98f --------
======== sawChange = false ========
2026-07-23 09:27:50.673959: -------- _replaceChildren: 30a3a84 --------
======== sawChange = false ========
2026-07-23 09:27:50.674329: -------- _replaceChildren: 37dd4e97 --------
2026-07-23 09:27:50.674465: _adoptChild, 37dd4e97 => 30a3a84, SemanticsNode#7(Rect.fromLTRB(540.0, 144.0, 740.0, 244.0), traversalChildIdentifier: _OverlayPortalState#7e590) => SemanticsNode#8(STALE, owner: null, Rect.fromLTRB(69.7, 78.0, 130.3, 95.0), label: "bad tooltip", textDirection: ltr)
2026-07-23 09:27:50.675359: attach, 30a3a84, SemanticsNode#8(STALE, owner: null, Rect.fromLTRB(69.7, 78.0, 130.3, 95.0), label: "bad tooltip", textDirection: ltr)
stack: ...
#1 SemanticsNode._replaceChildren (package:flutter/src/semantics/semantics.dart:3097:6)
#2 SemanticsNode.updateWith (package:flutter/src/semantics/semantics.dart:3778:5)
#3 _RenderObjectSemantics._buildSemanticsSubtree (package:flutter/src/rendering/object.dart:6258:12)
#4 _RenderObjectSemantics._produceSemanticsNode (package:flutter/src/rendering/object.dart:6272:5)
...
new: 30a3a84, SemanticsNode#8(dirty, Rect.fromLTRB(69.7, 78.0, 130.3, 95.0), label: "bad tooltip", textDirection: ltr)
======== sawChange = true ========
2026-07-23 09:27:50.676561: -------- _replaceChildren: 29f17e56 --------
======== sawChange = false ========
2026-07-23 09:27:50.676729: -------- _replaceChildren: 10889296 --------
======== sawChange = false ========
2026-07-23 09:27:50.676875: -------- _replaceChildren: 190eb487 --------
======== sawChange = false ========
2026-07-23 09:27:50.677010: -------- _replaceChildren: 211e9bc0 --------
======== sawChange = false ========
2026-07-23 09:27:50.677141: -------- _replaceChildren: cf98f --------
======== sawChange = false ========
2026-07-23 09:27:51.473208: -------- _replaceChildren: 30a3a84 --------
======== sawChange = false ========
2026-07-23 09:27:51.473603: -------- _replaceChildren: 37dd4e97 --------
======== sawChange = false ========
2026-07-23 09:27:51.473913: -------- _replaceChildren: 29f17e56 --------
======== sawChange = false ========
2026-07-23 09:27:51.474216: -------- _replaceChildren: 10889296 --------
======== sawChange = false ========
2026-07-23 09:27:51.474539: -------- _replaceChildren: 190eb487 --------
======== sawChange = false ========
2026-07-23 09:27:51.474937: -------- _replaceChildren: 211e9bc0 --------
======== sawChange = false ========
2026-07-23 09:27:51.475297: -------- _replaceChildren: cf98f --------
======== sawChange = false ========
2026-07-23 09:27:51.501495: -------- _replaceChildren: 29f17e56 --------
2026-07-23 09:27:51.501691: _dropChild, 29f17e56 => 3747acb0, SemanticsNode#4(dirty, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr, role: dialog) => SemanticsNode#6(Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr)
2026-07-23 09:27:51.503938: dettach, 3747acb0, SemanticsNode#6(Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr)
2026-07-23 09:27:51.505054: dettach, fdb5516, SemanticsNode#5(Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
2026-07-23 09:27:51.505758: _dropChild, 29f17e56 => 37dd4e97, SemanticsNode#4(dirty, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr, role: dialog) => SemanticsNode#7(Rect.fromLTRB(540.0, 144.0, 740.0, 244.0), traversalChildIdentifier: _OverlayPortalState#7e590)
2026-07-23 09:27:51.506952: dettach, 37dd4e97, SemanticsNode#7(Rect.fromLTRB(540.0, 144.0, 740.0, 244.0), traversalChildIdentifier: _OverlayPortalState#7e590)
2026-07-23 09:27:51.507483: dettach, 30a3a84, SemanticsNode#8(Rect.fromLTRB(69.7, 78.0, 130.3, 95.0), label: "bad tooltip", textDirection: ltr)
2026-07-23 09:27:51.508077: _dropChild, 3747acb0 => fdb5516, SemanticsNode#6(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr) => SemanticsNode#5(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
2026-07-23 09:27:51.509252: _adoptChild, 29f17e56 => fdb5516, SemanticsNode#4(dirty, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr, role: dialog) => SemanticsNode#5(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
2026-07-23 09:27:51.510485: attach, fdb5516, SemanticsNode#5(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
stack: ...
#1 SemanticsNode._replaceChildren (package:flutter/src/semantics/semantics.dart:3097:6)
#2 SemanticsNode.updateWith (package:flutter/src/semantics/semantics.dart:3778:5)
#3 _RenderObjectSemantics._buildSemanticsSubtree (package:flutter/src/rendering/object.dart:6258:12)
#4 _RenderObjectSemantics._produceSemanticsNode (package:flutter/src/rendering/object.dart:6272:5)
...
old: 3747acb0, SemanticsNode#6(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr)
old: 37dd4e97, SemanticsNode#7(STALE, owner: null, Rect.fromLTRB(540.0, 144.0, 740.0, 244.0), traversalChildIdentifier: _OverlayPortalState#7e590)
new: fdb5516, SemanticsNode#5(dirty, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
======== sawChange = true ========
2026-07-23 09:27:51.512809: -------- _replaceChildren: 10889296 --------
======== sawChange = false ========
2026-07-23 09:27:51.513011: -------- _replaceChildren: 190eb487 --------
======== sawChange = false ========
2026-07-23 09:27:51.513186: -------- _replaceChildren: 211e9bc0 --------
======== sawChange = false ========
2026-07-23 09:27:51.513345: -------- _replaceChildren: cf98f --------
======== sawChange = false ========
2026-07-23 09:27:52.353982: -------- _replaceChildren: 35ab8895 --------
======== sawChange = false ========
2026-07-23 09:27:52.354179: -------- _replaceChildren: 29f17e56 --------
2026-07-23 09:27:52.354246: _dropChild, 29f17e56 => fdb5516, SemanticsNode#4(dirty, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), role: dialog) => SemanticsNode#5(Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
2026-07-23 09:27:52.355126: dettach, fdb5516, SemanticsNode#5(Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
2026-07-23 09:27:52.355539: _adoptChild, 29f17e56 => 3747acb0, SemanticsNode#4(dirty, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), role: dialog) => SemanticsNode#6(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr)
2026-07-23 09:27:52.356303: attach, 3747acb0, SemanticsNode#6(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr)
2026-07-23 09:27:52.356690: attach, fdb5516, SemanticsNode#5(STALE, owner: null, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
2026-07-23 09:27:52.356993: _adoptChild, 29f17e56 => 35ab8895, SemanticsNode#4(dirty, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), role: dialog) => SemanticsNode#9(STALE, owner: null, Rect.fromLTRB(540.0, 144.0, 740.0, 244.0), traversalChildIdentifier: _OverlayPortalState#7e590)
2026-07-23 09:27:52.357599: attach, 35ab8895, SemanticsNode#9(STALE, owner: null, Rect.fromLTRB(540.0, 144.0, 740.0, 244.0), traversalChildIdentifier: _OverlayPortalState#7e590)
stack: ...
#1 SemanticsNode._replaceChildren (package:flutter/src/semantics/semantics.dart:3097:6)
#2 SemanticsNode.updateWith (package:flutter/src/semantics/semantics.dart:3778:5)
#3 _RenderObjectSemantics._buildSemanticsSubtree (package:flutter/src/rendering/object.dart:6258:12)
#4 _RenderObjectSemantics._produceSemanticsNode (package:flutter/src/rendering/object.dart:6272:5)
...
old: fdb5516, SemanticsNode#5(dirty, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr)
new: 3747acb0, SemanticsNode#6(dirty, Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr)
new: 35ab8895, SemanticsNode#9(dirty, Rect.fromLTRB(540.0, 144.0, 740.0, 244.0), traversalChildIdentifier: _OverlayPortalState#7e590)
======== sawChange = true ========
2026-07-23 09:27:52.360040: -------- _replaceChildren: 10889296 --------
======== sawChange = false ========
2026-07-23 09:27:52.360288: -------- _replaceChildren: 190eb487 --------
======== sawChange = false ========
2026-07-23 09:27:52.360441: -------- _replaceChildren: 211e9bc0 --------
======== sawChange = false ========
2026-07-23 09:27:52.360578: -------- _replaceChildren: cf98f --------
======== sawChange = false ========
2026-07-23 09:27:52.369454: -------- _replaceChildren: 32fcf788 --------
======== sawChange = false ========
2026-07-23 09:27:52.369683: -------- _replaceChildren: 35ab8895 --------
2026-07-23 09:27:52.369778: _adoptChild, 35ab8895 => 32fcf788, SemanticsNode#9(Rect.fromLTRB(540.0, 144.0, 740.0, 244.0), traversalChildIdentifier: _OverlayPortalState#7e590) => SemanticsNode#10(STALE, owner: null, Rect.fromLTRB(69.7, 78.0, 130.3, 95.0), label: "bad tooltip", textDirection: ltr)
2026-07-23 09:27:52.370738: attach, 32fcf788, SemanticsNode#10(STALE, owner: null, Rect.fromLTRB(69.7, 78.0, 130.3, 95.0), label: "bad tooltip", textDirection: ltr)
stack: ...
#1 SemanticsNode._replaceChildren (package:flutter/src/semantics/semantics.dart:3097:6)
#2 SemanticsNode.updateWith (package:flutter/src/semantics/semantics.dart:3778:5)
#3 _RenderObjectSemantics._buildSemanticsSubtree (package:flutter/src/rendering/object.dart:6258:12)
#4 _RenderObjectSemantics._produceSemanticsNode (package:flutter/src/rendering/object.dart:6272:5)
...
new: 32fcf788, SemanticsNode#10(dirty, Rect.fromLTRB(69.7, 78.0, 130.3, 95.0), label: "bad tooltip", textDirection: ltr)
======== sawChange = true ========
2026-07-23 09:27:52.372299: -------- _replaceChildren: 29f17e56 --------
======== sawChange = false ========
2026-07-23 09:27:52.372526: -------- _replaceChildren: 10889296 --------
======== sawChange = false ========
2026-07-23 09:27:52.373345: -------- _replaceChildren: 190eb487 --------
======== sawChange = false ========
2026-07-23 09:27:52.373795: -------- _replaceChildren: 211e9bc0 --------
======== sawChange = false ========
2026-07-23 09:27:52.374156: -------- _replaceChildren: cf98f --------
======== sawChange = false ========
2026-07-23 09:27:53.190395: -------- _replaceChildren: 32fcf788 --------
======== sawChange = false ========
2026-07-23 09:27:53.191011: -------- _replaceChildren: 35ab8895 --------
======== sawChange = false ========
2026-07-23 09:27:53.191467: -------- _replaceChildren: 29f17e56 --------
======== sawChange = false ========
2026-07-23 09:27:53.192047: -------- _replaceChildren: 10889296 --------
======== sawChange = false ========
2026-07-23 09:27:53.192603: -------- _replaceChildren: 190eb487 --------
======== sawChange = false ========
2026-07-23 09:27:53.193190: -------- _replaceChildren: 211e9bc0 --------
======== sawChange = false ========
2026-07-23 09:27:53.193805: -------- _replaceChildren: cf98f --------
======== sawChange = false ========
2026-07-23 09:27:53.221394: -------- _replaceChildren: 29f17e56 --------
2026-07-23 09:27:53.221584: _dropChild, 29f17e56 => 3747acb0, SemanticsNode#4(dirty, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr, role: dialog) => SemanticsNode#6(Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr)
2026-07-23 09:27:53.223268: dettach, 3747acb0, SemanticsNode#6(Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr)
2026-07-23 09:27:53.224115: _dropChild, 29f17e56 => 35ab8895, SemanticsNode#4(dirty, Rect.fromLTRB(0.0, 0.0, 1280.0, 720.0), traversalParentIdentifier: _OverlayPortalState#18de2, tooltip: "good tooltip", textDirection: ltr, role: dialog) => SemanticsNode#9(Rect.fromLTRB(540.0, 144.0, 740.0, 244.0), traversalChildIdentifier: _OverlayPortalState#7e590)
2026-07-23 09:27:53.225472: dettach, 35ab8895, SemanticsNode#9(Rect.fromLTRB(540.0, 144.0, 740.0, 244.0), traversalChildIdentifier: _OverlayPortalState#7e590)
2026-07-23 09:27:53.226023: dettach, 32fcf788, SemanticsNode#10(Rect.fromLTRB(69.7, 78.0, 130.3, 95.0), label: "bad tooltip", textDirection: ltr)
==== asserts ! stack:
_AssertionError._doThrowNew (/DATA1/FLUTTER_SDK/flutter.latest/bin/cache/pkg/sky_engine/lib/_internal/vm/lib/errors_patch.dart:67)
_AssertionError._throwNew (/DATA1/FLUTTER_SDK/flutter.latest/bin/cache/pkg/sky_engine/lib/_internal/vm/lib/errors_patch.dart:49)
SemanticsNode._replaceChildren (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/semantics/semantics.dart:3013)
SemanticsNode.updateWith (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/semantics/semantics.dart:3779)
_RenderObjectSemantics._buildSemanticsSubtree (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6258)
_RenderObjectSemantics._produceSemanticsNode (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6272)
_RenderObjectSemantics._buildSemantics (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6205)
_RenderObjectSemantics._buildSemanticsSubtree (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6241)
_RenderObjectSemantics._produceSemanticsNode (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6272)
_RenderObjectSemantics._buildSemantics (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6205)
_RenderObjectSemantics._buildSemanticsSubtree (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6241)
_RenderObjectSemantics._produceSemanticsNode (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6272)
_RenderObjectSemantics._buildSemantics (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6205)
_RenderObjectSemantics._buildSemanticsSubtree (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6241)
_RenderObjectSemantics._produceSemanticsNode (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6272)
_RenderObjectSemantics._buildSemantics (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6205)
_RenderObjectSemantics._buildSemanticsSubtree (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6241)
_RenderObjectSemantics.ensureSemanticsNode (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:6177)
PipelineOwner.flushSemantics (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:1636)
PipelineOwner.flushSemantics (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/object.dart:1653)
RendererBinding.drawFrame (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/binding.dart:650)
WidgetsBinding.drawFrame (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/widgets/binding.dart:1573)
RendererBinding._handlePersistentFrameCallback (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/rendering/binding.dart:509)
SchedulerBinding._invokeFrameCallback (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/scheduler/binding.dart:1430)
SchedulerBinding.handleDrawFrame (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/scheduler/binding.dart:1345)
SchedulerBinding._handleDrawFrame (/DATA1/FLUTTER_SDK/flutter.latest/packages/flutter/lib/src/scheduler/binding.dart:1198)
_invoke (/DATA1/FLUTTER_SDK/flutter.latest/bin/cache/pkg/sky_engine/lib/ui/hooks.dart:423)
PlatformDispatcher._drawFrame (/DATA1/FLUTTER_SDK/flutter.latest/bin/cache/pkg/sky_engine/lib/ui/platform_dispatcher.dart:447)
_drawFrame (/DATA1/FLUTTER_SDK/flutter.latest/bin/cache/pkg/sky_engine/lib/ui/hooks.dart:395)
# select frame 2:
child
SemanticsNode (SemanticsNode#5(Rect.fromLTRB(609.4, 104.0, 670.6, 124.0), label: "good text", textDirection: ltr))
_actions: Map (0 items)
_actionsAsBits: 0
_areUserActionsBlocked: false
_attributedDecreasedValue: AttributedString (LateInitializationError: Field '_toStringVisiting@10040228' has been assigned during initialization.)
_attributedHint: AttributedString (AttributedString('', attributes: []))
_attributedIncreasedValue: AttributedString (LateInitializationError: Field '_toStringVisiting@10040228' has been assigned during initialization.)
_attributedLabel: AttributedString (AttributedString('good text', attributes: []))
_attributedValue: AttributedString (AttributedString('', attributes: []))
_children: List (0 items)
_controlsNodes: null
_currentValueLength: null
_customSemanticsActions: Map (0 items)
_dead: false
_debugPreviousSnapshot: List (0 items)
_depth: 6
_dirty: false
_flags: SemanticsFlags
_headingLevel: 0
_hintOverrides: null
_hitTestBehavior: SemanticsHitTestBehavior (SemanticsHitTestBehavior.defer)
_id: 5
_identifier: ""
_inputType: SemanticsInputType (SemanticsInputType.none)
_isMergedIntoParent: false
_isMultiline: false
_linkUrl: null
_locale: null
_maxValue: null
_maxValueLength: null
_mergeAllDescendantsIntoThisNode: false
_minValue: null
_owner: SemanticsOwner (SemanticsOwner#45594)
_parent: null
_platformViewId: null
_rect: Rect (Rect.fromLTRB(0.0, 0.0, 61.2, 20.0))
_role: SemanticsRole (SemanticsRole.none)
_scrollChildCount: null
_scrollExtentMax: null
_scrollExtentMin: null
_scrollIndex: null
_scrollPosition: null
_showOnScreen: Closure
_sortKey: null
_textDirection: TextDirection (TextDirection.ltr)
_textSelection: null
_tooltip: ""
_transform: Matrix4 ([0] [1.0,0.0,0.0,609.3841094970703]
[1] [0.0,1.0,0.0,104.0]
[2] [0.0,0.0,1.0,0.0]
[3] [0.0,0.0,0.0,1.0]
)
_traversalChildIdentifier: null
_traversalChildTransform: null
_traversalParent: null
_traversalParentIdentifier: null
_validationResult: SemanticsValidationResult (SemanticsValidationResult.none)
areUserActionsBlocked: false
attached: true
attributedDecreasedValue: AttributedString (AttributedString('', attributes: []))
attributedHint: AttributedString (AttributedString('', attributes: []))
attributedIncreasedValue: AttributedString (AttributedString('', attributes: []))
attributedLabel: AttributedString (AttributedString('good text', attributes: []))
attributedValue: AttributedString (AttributedString('', attributes: []))
childrenCount: 0
childrenCountInTraversalOrder: 0
controlsNodes: null
currentValueLength: null
debugIsDirty: false
decreasedValue: ""
depth: 6
flagsCollection: SemanticsFlags
hasChildren: false
hashCode: 266032406
headingLevel: 0
hint: ""
hintOverrides: null
hitTestBehavior: SemanticsHitTestBehavior (SemanticsHitTestBehavior.defer)
id: 5
identifier: ""
increasedValue: ""
indexInParent: null
inputType: SemanticsInputType (SemanticsInputType.none)
isInvisible: false
isMergedIntoParent: false
isMultiline: false
isPartOfNodeMerging: false
key: null
label: "good text"
linkUrl: null
maxValue: null
maxValueLength: null
mergeAllDescendantsIntoThisNode: false
minValue: null
owner: SemanticsOwner (SemanticsOwner#45594)
parent: null
parentPaintClipRect: null
parentSemanticsClipRect: null
platformViewId: null
rect: Rect (Rect.fromLTRB(0.0, 0.0, 61.2, 20.0))
role: SemanticsRole (SemanticsRole.none)
runtimeType: Type (SemanticsNode)
scrollChildCount: null
scrollExtentMax: null
scrollExtentMin: null
scrollIndex: null
scrollPosition: null
sortKey: null
tags: null
textDirection: TextDirection (TextDirection.ltr)
textSelection: null
tooltip: ""
transform: Matrix4 ([0] [1.0,0.0,0.0,609.3841094970703]
[1] [0.0,1.0,0.0,104.0]
[2] [0.0,0.0,1.0,0.0]
[3] [0.0,0.0,0.0,1.0]
)
traversalChildIdentifier: null
traversalParent: null
traversalParentIdentifier: null
validationResult: SemanticsValidationResult (SemanticsValidationResult.none)
value: ""
Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.44.5, on Debian GNU/Linux 12 (bookworm) 6.1.0-49-amd64, locale en_US.UTF-8) [30ms]
• Flutter version 3.44.5 on channel stable at /DATA1/FLUTTER_SDK/flutter.latest
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision f94f4fc76b (2 weeks ago), 2026-07-06 11:19:24 -0700
• Engine revision 83675ed276
• Dart version 3.12.2
• DevTools version 2.57.0
• Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, enable-custom-devices, 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 [23ms]
✗ Unable to locate Android SDK.
Install Android Studio from: https://developer.android.com/studio/index.html
On first launch it will assist you in installing the Android SDK components.
(or visit https://flutter.dev/to/linux-android-setup for detailed instructions).
If the Android SDK has been installed to a custom location, please use
`flutter config --android-sdk` to update to that location.
[✓] Chrome - develop for the web [11ms]
• Chrome at google-chrome
[✓] Linux toolchain - develop for Linux desktop [161ms]
• Debian clang version 14.0.6
• cmake version 3.25.1
• ninja version 1.11.1
• pkg-config version 1.8.1
• GL_EXT_framebuffer_blit: no
• GL_EXT_texture_format_BGRA8888: no
[✓] Connected device (2 available) [61ms]
• Linux (desktop) • linux • linux-x64 • Debian GNU/Linux 12 (bookworm) 6.1.0-49-amd64
• Chrome (web) • chrome • web-javascript • Google Chrome 149.0.7827.200
[!] Network resources [131.1s]
✗ A network error occurred while checking "https://maven.google.com/": Connection failed
! Doctor found issues in 2 categories.Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work lista: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)Accessibility, e.g. VoiceOver or TalkBack. (aka a11y)team-accessibilityOwned by Framework Accessibility team (i.e. responsible for accessibility code in flutter/flutter)Owned by Framework Accessibility team (i.e. responsible for accessibility code in flutter/flutter)triaged-accessibilityTriaged by Framework Accessibility teamTriaged by Framework Accessibility team
Activity
[-]SemanticsNode._replaceChildren may cause inconsistent parent/children pointers[/-][+]SemanticsNode._replaceChildren may cause inconsistent parent/children pointers, and eventually asserts[/+]xiangh-2018 commentedon Jul 23, 2026
This (#187198 (comment)) looks similar.
xiangh-2018 commentedon Jul 23, 2026
This might be a simple fix:
But I'm afraid this behavior is triggered by some recent addition: this code fragment has been around for years, and the assert only pops after a recent upgrade from 3.38.5 to 3.44.5;
suryaKommana2662 commentedon Jul 23, 2026
@xiangh-2018 I was able to reproduce the reported issue locally using the provided sample. Following the reported steps of hovering over
bad text, moving the pointer away, and repeating the hover/unhover sequence, I encountered the following assertion:The stack trace points to
SemanticsNode._replaceChildrenduring the semantics tree update/flush process, which matches the behavior described in this issue.I also noticed the related behavior reported in #187198. Although both issues trigger the same
!child.attachedassertion inSemanticsNode._replaceChildren, the reproduction scenarios are different. I'll keep this issue open for now so the team-accessibility can investigate whether both issues share the same underlying cause or require separate fixes.madenvel commentedon Jul 27, 2026
Another assert variant, likely the same stale parent/children pointers. On Flutter 3.44.8 stable, the semantics flush asserts in
_SemanticsGeometry.computeChildGeometry:
'package:flutter/src/rendering/object.dart': Failed assertion: line 6670 pos 12: 'identical(childRenderObject, parentRenderObject)': is not true. #2 _SemanticsGeometry.computeChildGeometry (rendering/object.dart:6670) #3 _RenderObjectSemantics._updateChildGeometry (rendering/object.dart:6108) #4 _RenderObjectSemantics.ensureGeometry (rendering/object.dart:6098) #5 PipelineOwner.flushSemantics (rendering/object.dart:1590) i.e. the semantics tree holds a parent/child pair whose render objects are no longer ancestor/descendant. No tooltip interaction in my case — it fires intermittently around the app being backgrounded / losing focus, which dismisses hover state and overlays. Debug build, Linux desktop embedder (Fedora 44, GNOME with AT-SPI active). Happy to provide more detail if useful.
Fix semantics crash when clearing the queue
CanArslanDev commentedon Aug 3, 2026
@xiangh-2018 your analysis here pointed me at the right place, thanks. I went through the same code paths from the other direction (I have been chasing this in #187198, there under my other account @NL-CanArslan) and I think the missing link is that
attach()anddetach()disagree about stale child lists.detach()explicitly tolerates a stale_children, and comments on it:attach()has no such check (semantics.dart:3259), so a node holding a stale list re-attaches children that now belong to someone else. That produces a node withattached == trueandparent == null, which is precisely the state your log shows for n#5 before the assertion fires.That also explains why n#6 is not rebuilt, which you said you could not account for.
_RenderObjectSemantics._buildSemanticsshort circuits onbuilt(object.dart:6187) and never reaches_buildSemanticsSubtree, so the cached node's_childrenis never refreshed. Nothing setsbuilt = falsewhen a child is stolen, becausemarkNeedsBuild(object.dart:5748) only reacts to config, geometry and parentData, and there is no back reference from aSemanticsNodeto the_RenderObjectSemanticsholding it incachedSemanticsNode.The three line alternative to your patch is to mirror the guard
detach()already has:if (_children != null) { for (final SemanticsNode child in _children!) { - child.attach(owner); + // The list of children may be stale and may contain nodes that have + // been assigned to a different parent. + if (child.parent == this) { + child.attach(owner); + } } }I reduced your repro to a widget test, ran it against 3.44.8 stable and it fails with the same
!child.attachedat semantics.dart:3008. With the guard it passes, and the framework suites stay green (892 intest/semanticsandtest/rendering, 7014 intest/widgetswith only pre-existing golden failures). Full writeup, both tests and the patch are in my comment on #187198: #187198 (comment)Two things about your proposed patch, for what they are worth. Mutating
p._childrenworks against the invariant the framework documents indetach(), and_childrencan be theconst <SemanticsNode>[]thatupdateWithsubstitutes when the caller passes null (semantics.dart:3750), whereremovewould throw.On your suspicion that this came from a recent change, I think you are right and it is narrower than you might expect:
The traversal grafting machinery landed in stable at 3.41.0, which is inside your 3.38.5 to 3.44.5 upgrade window. Also worth knowing:
RawTooltipis built onOverlayPortal.overlayChildLayoutBuilder(raw_tooltip.dart:886), so your Tooltip repro is an OverlayPortal repro. Given that, and #182604 namingfccfa978a97in its title, I would say this issue, #187198 and #182604 are all the same defect.@madenvel your
identical(childRenderObject, parentRenderObject)variant at object.dart:6670 is the same corruption seen from the_RenderObjectSemanticsside, but I do not think the guard above covers it. That one probably needs the cache invalidation itself rather than a defensive check at attach time.xiangh-2018 commentedon Aug 4, 2026
Hello @CanArslanDev, thanks for the detailed explanation. I agree deep down this is also an OverlayPortal issue.
CanArslanDev commentedon Sep 6, 2026
Update on this one, since the fix moved after my earlier comment here.
I proposed mirroring the
detach()guard inattach()above. That is not what #190431 does any more. @chunhtai pointed out on the PR that the victim render object should have known its children were taken and marked itself, and after measuring it that turned out to be the actual gap:Both halves change whether a fragment forms its own semantics node. Only the first invalidates anything.
_didUpdateParentDatacallsmarkNeedsBuild;markSiblingConfigurationConflictassigns the flag and returns. That is how a fragment ends up keepingbuiltand itscachedSemanticsNodeacross a hide and show, so_buildSemanticsshort circuits,updateWithis never reached, and it goes back into the tree still holding_childrenthat belong to somebody else. Exactly the "n#6 is not rebuilt" step you could not account for, @xiangh-2018.The PR now marks the fragment when that flag changes, in
_marksConflictsInMergeGroup, which runs in the parent data phase so the rebuild happens in the same flush. Theattachguard and the copy on write repair are both dropped. Your repro from the top of this issue, reduced to a widget test, fails on master with the same'!child.attached'and passes with it.@madenvel, your
computeChildGeometryvariant is still not accounted for. I said earlier that I expected it to survive any fix here, but that was about the guard, and this version rebuilds the fragment, which refreshes its geometry too, so I honestly do not know either way. I could not reproduce it on macOS. If it would be useful I would rather see it tracked in its own issue than lose it when this one is closed by the PR.Rebuild a semantics fragment when its sibling conflict changes (flutt…
github-actions commentedon Oct 17, 2026
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.Rebuild a semantics fragment when its sibling conflict changes (flutt…