{"record":{"id":"4742e2f408bfe9bd","repo":"cefsharp/CefSharp","slug":"useanycpuassemblyresolver-has-already-been-called","errorCode":null,"errorMessage":"UseAnyCpuAssemblyResolver has already been called, call ","messagePattern":"UseAnyCpuAssemblyResolver has already been called, call ","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"CefSharp/CefRuntime.cs","lineNumber":37,"sourceCode":"        /// <summary>\n        /// When using AnyCPU the architecture specific version of CefSharp.Core.Runtime.dll\n        /// needs to be loaded (x64/x86).\n        /// This method subscribes to the <see cref=\"AppDomain.AssemblyResolve\"/> event\n        /// for <see cref=\"AppDomain.CurrentDomain\"/> and loads the CefSharp.Core.Runtime.dll\n        /// based on <see cref=\"Environment.Is64BitProcess\"/>.\n        /// This method MUST be called before you call Cef.Initialize, create your first ChromiumWebBrowser instance, basically\n        /// before anything CefSharp related happens. This method is part of CefSharp.dll which is an AnyCPU library and\n        /// doesn't have any references to the CefSharp.Core.Runtime.dll so it's safe to use.\n        /// </summary>\n        /// <param name=\"basePath\">\n        /// The path containing the x64/x86 folders which contain the CefSharp/CEF resources.\n        /// If null then AppDomain.CurrentDomain.SetupInformation.ApplicationBase will be used as the path.\n        /// (</param>\n        public static void SubscribeAnyCpuAssemblyResolver(string basePath = null)\n        {\n            if(currentDomainAssemblyResolveHandler != null)\n            {\n                throw new Exception(\"UseAnyCpuAssemblyResolver has already been called, call \");\n            }\n\n            if(basePath == null)\n            {\n                basePath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;\n            }\n\n            currentDomainAssemblyResolveHandler = (sender, args) =>\n            {\n                if (args.Name.StartsWith(\"CefSharp.Core.Runtime\"))\n                {\n                    string assemblyName = args.Name.Split(new[] { ',' }, 2)[0] + \".dll\";\n                    string archSpecificPath = Path.Combine(basePath,\n                                                           Environment.Is64BitProcess ? \"x64\" : \"x86\",\n                                                           assemblyName);\n\n                    return File.Exists(archSpecificPath)\n                               ? System.Reflection.Assembly.LoadFile(archSpecificPath)","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/cefsharp/CefSharp/blob/16bc6e0711a4945be17e8bc4bc7ccf9469f3fdec/CefSharp/CefRuntime.cs#L19-L55","documentation":"SubscribeAnyCpuAssemblyResolver hooks an AppDomain.AssemblyResolve handler to load the architecture-specific CefSharp.Core.Runtime.dll at runtime. It tracks whether it has already been called via a static field; calling it a second time throws because double-subscribing would create duplicate resolve handlers and unpredictable assembly loading.","triggerScenarios":"Calling CefRuntime.SubscribeAnyCpuAssemblyResolver() more than once in the same AppDomain without calling UnsubscribeAnyCpuAssemblyResolver in between.","commonSituations":"Application startup code and a DI container initializer both calling it. Test fixtures that re-run startup logic without cleanup. A library that calls it internally while the host app also calls it.","solutions":["Call SubscribeAnyCpuAssemblyResolver exactly once at application entry point.","If re-subscription is legitimately needed, call UnsubscribeAnyCpuAssemblyResolver first.","Guard the call with a check of whether CEF is already initialized or the resolver is already active."],"exampleFix":"// before — called in two places\nCefRuntime.SubscribeAnyCpuAssemblyResolver();\n// ... later, in another module ...\nCefRuntime.SubscribeAnyCpuAssemblyResolver(); // throws\n\n// after — call once, or unsubscribe first\nCefRuntime.UnsubscribeAnyCpuAssemblyResolver();\nCefRuntime.SubscribeAnyCpuAssemblyResolver(newBasePath);","handlingStrategy":"validation","validationCode":"// CefRuntime does not expose the internal flag publicly.\n// Track it yourself:\nprivate static int resolverSubscribed = 0;\n\nif (Interlocked.CompareExchange(ref resolverSubscribed, 1, 0) == 1)\n{\n    // already subscribed, skip or unsubscribe first\n    return;\n}\nCefRuntime.SubscribeAnyCpuAssemblyResolver(basePath);","typeGuard":null,"tryCatchPattern":"try\n{\n    CefRuntime.SubscribeAnyCpuAssemblyResolver(basePath);\n}\ncatch (Exception ex) when (ex.Message.Contains(\"already been called\"))\n{\n    Log.Info(\"AnyCPU resolver already subscribed — skipping\");\n}","preventionTips":["Call SubscribeAnyCpuAssemblyResolver exactly once in Program.Main or the app entry point.","If re-subscription is needed, call UnsubscribeAnyCpuAssemblyResolver first.","Avoid calling it from library initializers that may run multiple times."],"tags":["any-cpu","assembly-resolver","startup","configuration"],"backgroundTag":null,"analyzedSha":"16bc6e0711a4945be17e8bc4bc7ccf9469f3fdec","analyzedAt":"2026-08-13T19:57:05.828Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}