{"record":{"id":"b08a3c7247363a16","repo":"dotnet/wpf","slug":"iconnectionpoint-advise-returned-an-invalid-cookie","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/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Standard/NativeMethods.cs","lineNumber":1572,"sourceCode":"        [SuppressMessage(\"Microsoft.Naming\", \"CA2204:Literals should be spelled correctly\", MessageId = \"IConnectionPoint\")]\n        public SafeConnectionPointCookie(IConnectionPointContainer target, object sink, Guid eventId)\n            : base(true)\n        {\n            Verify.IsNotNull(target, \"target\");\n            Verify.IsNotNull(sink, \"sink\");\n            Verify.IsNotDefault(eventId, \"eventId\");\n\n            handle = IntPtr.Zero;\n\n            IConnectionPoint cp = null;\n            try\n            {\n                int dwCookie;\n                target.FindConnectionPoint(ref eventId, out cp);\n                cp.Advise(sink, out dwCookie);\n                if (dwCookie == 0)\n                {\n                    throw new InvalidOperationException(\"IConnectionPoint::Advise returned an invalid cookie.\");\n                }\n                handle = new IntPtr(dwCookie);\n                _cp = cp;\n                cp = null;\n            }\n            finally\n            {\n                Utility.SafeRelease(ref cp);\n            }\n        }\n\n        public void Disconnect()\n        {\n            ReleaseHandle();\n        }\n\n        [SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\")]\n","sourceCodeStart":1554,"sourceCodeEnd":1590,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Standard/NativeMethods.cs#L1554-L1590","documentation":"SafeConnectionPointCookie wraps a COM IConnectionPoint::Advise call that registers an event sink with a COM connection point and returns a cookie identifying the registration. This InvalidOperationException is thrown when Advise succeeds (does not throw) but returns a cookie of 0, which is not a valid registration handle. The library treats a zero cookie as evidence the COM object did not actually register the sink, so continuing would leave an unadviseable, corrupt connection.","triggerScenarios":"Calling SafeConnectionPointCookie's constructor with a COM target whose FindConnectionPoint succeeds for the given event IID but whose IConnectionPoint::Advise returns S_OK with dwCookie == 0 (e.g. a misbehaving or partially initialized COM source object).","commonSituations":"Hosting WPF WebBrowser/ActiveX controls (shDoccHost events, DWebBrowserEvents2) against non-standard or third-party COM objects that advertise connection points but fail to hand out real cookies; COM objects created before initialization completes or torn down concurrently.","solutions":["Ensure the COM source object is fully initialized and alive before constructing SafeConnectionPointCookie.","Verify the event GUID passed to the constructor matches a connection point the COM object genuinely supports (check FindConnectionPoint's returned cp is non-null).","Wrap sink registration in try-catch for InvalidOperationException and fall back to polling or alternative event mechanisms for that COM object.","If wrapping a third-party ActiveX control, test its Advise behavior; report or work around objects returning zero cookies."],"exampleFix":"// before\nvar cookie = new SafeConnectionPointCookie(activeX.Document, this, typeof(DWebBrowserEvents2).GUID);\n// after\nif (activeX.Document == null) throw new InvalidOperationException(\"Document not ready\");\ntry { var cookie = new SafeConnectionPointCookie(activeX.Document, this, typeof(DWebBrowserEvents2).GUID); }\ncatch (InvalidOperationException ex) { /* log: COM source did not register sink (cookie 0); use fallback */ }","handlingStrategy":"try-catch","validationCode":"if (comTarget == null) throw new InvalidOperationException(\"COM target not ready\");\n// no pre-call API to probe cookie; guard by constructing inside try-catch","typeGuard":null,"tryCatchPattern":"try {\n    var cookie = new SafeConnectionPointCookie(target, sink, eventId);\n} catch (InvalidOperationException ex) when (ex.Message.Contains(\"invalid cookie\")) {\n    log.Warn(\"COM Advise returned 0 cookie; sink not registered\", ex);\n    RegisterFallbackHandler();\n}","preventionTips":["Only advise against COM objects known to support the connection point (check FindConnectionPoint result).","Keep the COM source alive for the duration of the registration.","Test third-party ActiveX controls for correct Advise behavior before relying on their events."],"tags":["com-interop","wpf","connection-point","activex"],"backgroundTag":"internal-invariant-violation","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}