dotnet/wpf · error · InvalidOperationException
VisualTarget_AnotherTargetAlreadyConnected
Error message
VisualTarget_AnotherTargetAlreadyConnected
What it means
HostVisual.BeginHosting throws InvalidOperationException with 'VisualTarget_AnotherTargetAlreadyConnected' when the HostVisual already has a composition target attached. A HostVisual can only host one VisualTarget for its lifetime; re-hosting is an invalid state transition.
Solutions
- Create a new HostVisual for each VisualTarget connection
- Detach/dispose the old VisualTarget and HostVisual before hosting a new target
- Track whether the HostVisual is already connected and reuse the existing VisualTarget
Example fix
// before
hostVisual.BeginHosting(new VisualTarget(hostVisual)); // second call
// after
if (hostVisual.Target == null)
{
hostVisual.BeginHosting(new VisualTarget(hostVisual));
}
else
{
hostVisual = new HostVisual();
hostVisual.BeginHosting(new VisualTarget(hostVisual));
} Defensive patterns
Strategy: validation
Validate before calling
if (hostVisual.Target != null)
throw new InvalidOperationException("HostVisual already connected; create a new HostVisual."); Type guard
bool CanHost(HostVisual hv) => hv != null && hv.Target == null;
Try / catch
try { hostVisual.BeginHosting(target); }
catch (InvalidOperationException) { hostVisual = new HostVisual(); hostVisual.BeginHosting(target); } Prevention
- One VisualTarget per HostVisual for its lifetime
- Recreate the HostVisual when swapping render targets
- Track connection state to avoid double-hosting in retry/frame loops
When it happens
Trigger: Creating a second VisualTarget and calling BeginHosting with the same HostVisual instance that already has _target set (e.g. re-creating a VisualTarget on the same HostVisual after a render-thread reset).
Common situations: Multi-threaded UI scenarios that swap render targets dynamically (common in HwndSource/VisualTarget cross-thread rendering), where a new VisualTarget is created per frame or per device and reused with one HostVisual.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Animation_Invalid_DefaultValue
- Cannot remove signature from read-only file.
- Image_EncoderNoColorContext
- Image_EncoderNoGlobalMetadata
- Image_EncoderNoGlobalThumbnail
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/7a2e4326a02f03a9.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/HostVisual.cs:145
/// </summary>
internal void BeginHosting(VisualTarget target)
{
//
// This method is executed on the visual target thread.
//
Debug.Assert(target != null);
Debug.Assert(target.Dispatcher.Thread == Thread.CurrentThread);
using (CompositionEngineLock.Acquire())
{
//
// Check if another target is already hosted by this
// visual and throw exception if this is the case.
//
if (_target != null)
{
throw new InvalidOperationException(
SR.VisualTarget_AnotherTargetAlreadyConnected
);
}
_target = target;
//
// If HostVisual and VisualTarget on same thread, then call Invalidate
// directly. Otherwise post invalidate message to the host visual thread
// indicating that content update is required.
//
if (this.CheckAccess())
{
Invalidate();
}
else
{
Dispatcher.BeginInvoke(View on GitHub (pinned to 81131a70a4)