cefsharp/CefSharp · error · ArgumentException

Object already bound with name:{name}

Error message

Object already bound with name:{name}

What it means

Thrown by JavascriptObjectRepository.Register when an object is already registered under the requested name. Names are compared case-insensitively (StringComparison.OrdinalIgnoreCase) across all entries in the repository, so a second Register with a colliding name is rejected. Note the ArgumentException is constructed with the bound name as the paramName argument, which surfaces in some hosts as the parameter name.

Source

Thrown at CefSharp/Internals/JavascriptObjectRepository.cs:235

#if NETCOREAPP
            var isAsync = true;
#else
            if (!IsBrowserInitialized && !isAsync)
            {
                CefSharpSettings.WcfEnabled = true;
            }

            if (!CefSharpSettings.WcfEnabled && !isAsync)
            {
                throw new InvalidOperationException(@"To enable synchronous JS bindings set WcfEnabled true in CefSharpSettings before you create
                                                    your ChromiumWebBrowser instances.");
            }            
#endif

            //Validation name is unique
            if (objects.Values.Count(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase)) > 0)
            {
                throw new ArgumentException("Object already bound with name:" + name, name);
            }

            //Binding of System types is problematic, so we don't support it
            var type = value.GetType();
            if (type.IsPrimitive || type.BaseType.Namespace.StartsWith("System."))
            {
                throw new ArgumentException("Registering of .Net framework built in types is not supported, " +
                    "create your own Object and proxy the calls if you need to access a Window/Form/Control.", "value");
            }

            var jsObject = CreateJavascriptObject(rootObject: true);
            jsObject.Value = value;
            jsObject.Name = name;
            jsObject.JavascriptName = name;
            jsObject.IsAsync = isAsync;
            jsObject.Binder = options?.Binder;
            jsObject.MethodInterceptor = options?.MethodInterceptor;
#if !NETCOREAPP

View on GitHub (pinned to 16bc6e0711)

Solutions

  1. Choose a unique name for each registered object (case-insensitive).
  2. Call repository.UnRegister(name) before re-registering under the same name.
  3. Guard the registration: check repository.HasBoundObject(name) (or IsBoundObjectCached) before Register.
  4. Centralize all Register calls in one composition root to avoid duplicates across modules.

Example fix

// before
repository.Register("app", new AppVm());
repository.Register("App", new OtherVm()); // collides (case-insensitive)

// after
if (!repository.HasBoundObject("app"))
{
    repository.Register("app", new AppVm());
}
Defensive patterns

Strategy: validation

Validate before calling

if (repository.HasBoundObject(name))
{
    repository.UnRegister(name); // or throw/log
}
repository.Register(name, obj);

Try / catch

try { repository.Register(name, obj); }
catch (ArgumentException ex) when (ex.Message.Contains("Object already bound"))
{ /* log duplicate registration, use existing object */ }

Prevention

When it happens

Trigger: Two calls to IJavascriptObjectRepository.Register("name", obj) (or names differing only by case) targeting the same repository instance; re-registering after a hot-reload or navigation without first calling UnRegister; multiple view models binding different objects under the same logical name.

Common situations: Reusable control registered in more than one place; DI scope creating duplicate registrations; name typo colliding with an existing object; leftover registration from a previous page not cleaned up.

Related errors


AI-assisted analysis of cefsharp/CefSharp@16bc6e0711 (2026-08-13). Data as JSON: /api/errors/dd2ab6ddcf60aa80. Report an issue: GitHub.