dotnet/maui · error · InvalidOperationException
IConnectionPoint::Advise returned an invalid cookie.
Error message
IConnectionPoint::Advise returned an invalid cookie.
What it means
SafeConnectionPointCookie constructor throws InvalidOperationException("IConnectionPoint::Advise returned an invalid cookie.") when COM's IConnectionPoint.Advise returns a dwCookie of 0 after FindConnectionPoint succeeded. Cookie 0 is an invalid advisory cookie, meaning the COM event subscription did not actually register the sink, so subsequent event delivery would silently fail.
Source
Thrown at src/Compatibility/Core/src/WPF/Microsoft.Windows.Shell/Standard/NativeMethods.cs:1642
[SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "IConnectionPoint")]
public SafeConnectionPointCookie(IConnectionPointContainer target, object sink, Guid eventId)
: base(true)
{
Verify.IsNotNull(target, "target");
Verify.IsNotNull(sink, "sink");
Verify.IsNotDefault(eventId, "eventId");
handle = IntPtr.Zero;
IConnectionPoint cp = null;
try
{
int dwCookie;
target.FindConnectionPoint(ref eventId, out cp);
cp.Advise(sink, out dwCookie);
if (dwCookie == 0)
{
throw new InvalidOperationException("IConnectionPoint::Advise returned an invalid cookie.");
}
handle = new IntPtr(dwCookie);
_cp = cp;
cp = null;
}
finally
{
Utility.SafeRelease(ref cp);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public void Disconnect()
{
ReleaseHandle();
}
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]View on GitHub (pinned to f377ff1c5e)
Solutions
- Verify the sink object is COM-visible and matches the expected dispatch interface.
- Ensure the calling thread's apartment (STA/MTA) matches the COM component's requirements.
- Subscribe before the component is disposed and unsubscribe cleanly to avoid teardown races.
- If the source component is in a bad state, recreate it before retrying Advise.
Example fix
// before
var cookie = new SafeConnectionPointCookie((IConnectionPointContainer)comObj, sink, eventId);
// after
comObj.SetApartmentState(ApartmentState.STA);
if (sink is IComVisible)
var cookie = new SafeConnectionPointCookie((IConnectionPointContainer)comObj, sink, eventId);
else
throw new InvalidOperationException("sink is not COM-visible"); Defensive patterns
Strategy: validation
Validate before calling
if (sink == null || !sink.GetType().IsCOMVisible) throw new ArgumentException("sink must be COM-visible");
var cookie = new SafeConnectionPointCookie(container, sink, eventId); Type guard
static bool IsValidSink(object sink) => sink != null && sink.GetType().IsCOMVisible;
Try / catch
try { var cookie = new SafeConnectionPointCookie(container, sink, eventId); }
catch (InvalidOperationException ex) when (ex.Message.Contains("invalid cookie"))
{ /* recreate COM component, fix apartment, then retry Advise */ } Prevention
- Ensure the sink is COM-visible and matches the dispatch interface.
- Match STA/MTA apartment requirements of the COM component.
- Subscribe before component disposal; unsubscribe cleanly during teardown.
When it happens
Trigger: Subscribing to COM connection-point events (e.g. shell or DWebBrowserEvents) where Advise returns 0; passing a sink that the source rejected; race between Advise and connection-point teardown.
Common situations: Hosting a COM component (WebBrowser, shell, automation) whose connection point is in a bad state; passing a non-com-visible sink; subscribing during shutdown; COM apartment mismatches causing Advise to fail.
Related errors
- ActivateApplication failed (HRESULT=0x{0:X8})
- Unable to find the required services. Please add all the req
- RootComponent requires a value for its Selector property, bu
- RootComponent requires a value for its ComponentType propert
- ContentLoader
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/fe82f6598cd0a32e.
Report an issue: GitHub.