Repository navigation
Bug: itemviewer-breadcrumb-pipeline-lifecycle #488
Description
Activity
Correction to Defect 1, plus two adjacent defects in
BreadcrumbItemViewerLifecycleCoordinator.csRaised from preparation research for epic #136 child F12 (issue #495), which owns
QuickFiler/Viewers/BreadcrumbItemViewerLifecycleCoordinator.cs— the file this issue's Defect 1
reasons about from theItemViewer.Breadcrumb.csside.Defect 1 is partly inaccurate — the previous host is disposed
Defect 1 currently states that
ReleaseHostCore()"unsubscribesPopupMessengerReadyand calls
coordinator.Release()(:300-303), but does not callIBreadcrumbDropDownHost.Dispose()."Verified directly on the integration branch:
coordinator.Release()does dispose the host.// QuickFiler/Viewers/BreadcrumbDropDownOpenCoordinator.cs:150-159 internal void Release() { if (!Invalidate(release: true)) return; _ = _operations.PostAsync(() => { _detachPopupMessenger(); _host.Dispose(); }); }
So the disposal is present but asynchronous and fire-and-forget — posted through
_operations.PostAsyncwith the returned task discarded. The residual risk is therefore narrower
than "never disposed", but it is not nil, and it is arguably harder to reason about:- disposal is deferred to a posted lambda, so it does not happen before the replacement host is
constructed; Invalidate(release: true)returningfalseskips it entirely;- the discarded task means a fault in
_detachPopupMessenger()or_host.Dispose()is swallowed.
Suggest rewording Defect 1 from "the first host is never disposed" to "the first host is disposed
only via a discarded posted lambda, with no ordering guarantee against construction of its
replacement and no observation of failure." TheBreadcrumbDropDownIntegrationTests.cs:308evidence
cited in the issue still stands on its own terms.Additional defect —
SetBridgeCoordinatorreplaces without disposing, whileDispose()disposesBreadcrumbItemViewerLifecycleCoordinator.cs:64-77. On replacement the method calls
UnsubscribeBridge()and then overwrites_bridgeCoordinator, but never disposes the outgoing
instance — whereasDispose()(:216) does dispose it. The type is therefore inconsistent about
whether it owns the bridge coordinator: it owns it at teardown but not at replacement.This is unreachable today only because of the reference-equality guard at
:66-69. That is the
same guard family this issue's Defect 3 proposes to make stricter by comparing providers. If
Defect 3's fix allows a genuinely different bridge coordinator to be installed on an already-
initialized viewer, this replacement path becomes live and will leak the outgoing coordinator's
BreadcrumbMessengerHuband its four event subscriptions. The two should be fixed together.Additional defect —
Reset()detaches two surfaces with different synchronyBreadcrumbItemViewerLifecycleCoordinator.cs:197.Reset()detaches the collapsed surface
synchronously but the popup surface only via a posted lambda. This is the same class as this issue's
Defect 2 (an operation whose correctness depends on whether the dispatcher post runs inline),
at a different file and site. Worth folding into Defect 2's fix so the ordering rule is applied
once rather than per call site.Scope note
None of the above is being fixed under #495, whose epic carries a no-behavior-change NFR. #495's
tests pin current behavior. Whoever fixes this issue should expect to update those tests as part
of the fix rather than treat the change as a regression.- disposal is deferred to a posted lambda, so it does not happen before the replacement host is
- added a commit that references this issue
on Aug 8, 2026
Summary
Five lifecycle defects in
QuickFiler/Viewers/ItemViewer.Breadcrumb.cs. All are out of scope to fixunder epic #136's no-behavior-change NFR. Two of them (Defects 1 and 3) are reachable through the
existing pooled-viewer reuse path in production.
Environment
(not provided in potential file)
Steps to Reproduce
(not provided in potential file)
Expected Behavior
(not provided in potential file)
Actual Behavior
(not provided in potential file)
Logs / Screenshots
(not provided in potential file)
Impact / Severity
(not provided in potential file)
Source
From: docs/features/potential/2026-08-07-itemviewer-breadcrumb-pipeline-lifecycle.md