{"record":{"id":"fe82f6598cd0a32e","repo":"dotnet/maui","slug":"iconnectionpoint-advise-returned-an-invalid-cooki","errorCode":null,"errorMessage":"IConnectionPoint::Advise returned an invalid cookie.","messagePattern":"IConnectionPoint::Advise returned an invalid cookie\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Compatibility/Core/src/WPF/Microsoft.Windows.Shell/Standard/NativeMethods.cs","lineNumber":1642,"sourceCode":"\t\t[SuppressMessage(\"Microsoft.Naming\", \"CA2204:Literals should be spelled correctly\", MessageId = \"IConnectionPoint\")]\n\t\tpublic SafeConnectionPointCookie(IConnectionPointContainer target, object sink, Guid eventId)\n\t\t\t: base(true)\n\t\t{\n\t\t\tVerify.IsNotNull(target, \"target\");\n\t\t\tVerify.IsNotNull(sink, \"sink\");\n\t\t\tVerify.IsNotDefault(eventId, \"eventId\");\n\n\t\t\thandle = IntPtr.Zero;\n\n\t\t\tIConnectionPoint cp = null;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tint dwCookie;\n\t\t\t\ttarget.FindConnectionPoint(ref eventId, out cp);\n\t\t\t\tcp.Advise(sink, out dwCookie);\n\t\t\t\tif (dwCookie == 0)\n\t\t\t\t{\n\t\t\t\t\tthrow new InvalidOperationException(\"IConnectionPoint::Advise returned an invalid cookie.\");\n\t\t\t\t}\n\t\t\t\thandle = new IntPtr(dwCookie);\n\t\t\t\t_cp = cp;\n\t\t\t\tcp = null;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tUtility.SafeRelease(ref cp);\n\t\t\t}\n\t\t}\n\n\t\t[SuppressMessage(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n\t\tpublic void Disconnect()\n\t\t{\n\t\t\tReleaseHandle();\n\t\t}\n\n\t\t[SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\")]","sourceCodeStart":1624,"sourceCodeEnd":1660,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Compatibility/Core/src/WPF/Microsoft.Windows.Shell/Standard/NativeMethods.cs#L1624-L1660","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvar cookie = new SafeConnectionPointCookie((IConnectionPointContainer)comObj, sink, eventId);\n\n// after\ncomObj.SetApartmentState(ApartmentState.STA);\nif (sink is IComVisible)\n    var cookie = new SafeConnectionPointCookie((IConnectionPointContainer)comObj, sink, eventId);\nelse\n    throw new InvalidOperationException(\"sink is not COM-visible\");","handlingStrategy":"validation","validationCode":"if (sink == null || !sink.GetType().IsCOMVisible) throw new ArgumentException(\"sink must be COM-visible\");\nvar cookie = new SafeConnectionPointCookie(container, sink, eventId);","typeGuard":"static bool IsValidSink(object sink) => sink != null && sink.GetType().IsCOMVisible;","tryCatchPattern":"try { var cookie = new SafeConnectionPointCookie(container, sink, eventId); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"invalid cookie\"))\n{ /* recreate COM component, fix apartment, then retry Advise */ }","preventionTips":["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."],"tags":["wpf","com","interop","connection-point","events"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}