cefsharp/CefSharp · error · DevToolsClientException

{prop.Name} is required

Error message

{prop.Name} is required

What it means

In the attribute-driven serialisation path of DevToolsDomainEntityBase (the one keyed off [DataMember]-style attributes plus DisallowNullAttribute), a property flagged as required whose runtime value is null triggers a DevToolsClientException: '<propName> is required'. The property name used in the message is the C# property name (prop.Name), not the serialisation Name from the attribute. This is caller-data validation before the entity is converted to its DevTools parameter dictionary.

Source

Thrown at CefSharp.Core/DevTools/DevToolsDomainEntityBase.cs:155

            foreach (var prop in properties)
            {
                var propertyAttribute = (System.Text.Json.Serialization.JsonPropertyNameAttribute)Attribute.GetCustomAttribute(prop, typeof(System.Text.Json.Serialization.JsonPropertyNameAttribute), false);

                //Only add members that have JsonPropertyNameAttribute
                if (propertyAttribute == null)
                {
                    continue;
                }

                var propertyName = propertyAttribute.Name;
                var propertyRequired = Attribute.IsDefined(prop, typeof(System.Diagnostics.CodeAnalysis.DisallowNullAttribute));
                
                var propertyValue = prop.GetValue(this);

                if (propertyRequired && propertyValue == null)
                {
                    throw new DevToolsClientException(prop.Name + " is required");
                }

                //Not required and value null, don't add to dictionary
                if (propertyValue == null)
                {
                    continue;
                }

                var propertyValueType = propertyValue.GetType();

                if (typeof(DevToolsDomainEntityBase).IsAssignableFrom(propertyValueType))
                {
                    propertyValue = ((DevToolsDomainEntityBase)(propertyValue)).ToDictionary();
                }
                else if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(IList<>) && typeof(DevToolsDomainEntityBase).IsAssignableFrom(prop.PropertyType.GetGenericArguments()[0]))
                {
                    var values = new List<IDictionary<string, object>>();
                    foreach (var value in (IEnumerable)propertyValue)

View on GitHub (pinned to 16bc6e0711)

Solutions

  1. Read the exception message for the exact property name, then set that property on the entity before sending.
  2. Use the generated domain client's typed options classes so the compiler/intellisense surfaces required fields at design time.
  3. Add a unit test that constructs each entity you send and asserts no DevToolsClientException on serialisation.
  4. When upgrading CefSharp, diff the DevTools domain entities for newly-required fields.

Example fix

// before
var cmd = new SomeDomainRequest { Url = url }; // 'Transition' is required -> throws
await client.SomeDomain.ExecuteAsync(cmd);

// after
var cmd = new SomeDomainRequest { Url = url, Transition = "reload" };
await client.SomeDomain.ExecuteAsync(cmd);
Defensive patterns

Strategy: validation

Validate before calling

// Validate required (DisallowNull) members before serialising.
static void AssertRequired(object entity)
{
    foreach (var p in entity.GetType().GetProperties())
        if (Attribute.IsDefined(p, typeof(System.Diagnostics.CodeAnalysis.DisallowNullAttribute)) && p.GetValue(entity) == null)
            throw new InvalidOperationException($"{p.Name} is required");
}

Type guard

public static bool HasAllRequired(object entity) =>
    entity.GetType().GetProperties()
        .Where(p => Attribute.IsDefined(p, typeof(System.Diagnostics.CodeAnalysis.DisallowNullAttribute)))
        .All(p => p.GetValue(entity) != null);

Try / catch

try { await client.SomeDomain.ExecuteAsync(req); }
catch (DevToolsClientException ex) when (ex.Message.EndsWith(" is required"))
{ /* set the named property and retry */ }

Prevention

When it happens

Trigger: Constructing a generated DevTools domain request/response entity (e.g. Network.SetExtraHTTPHeaders, Page.PrintToPDF options) and leaving a [DisallowNull] / required property unset; passing a DTO built via object initialiser that omits a mandatory field; reflective serialisation invoked by ExecuteDevToolsMethodAsync when it builds the parameters dictionary.

Common situations: Forgetting a required field on a PrintToPDF or Network command; upgrading CefSharp where a previously-optional field became required and now throws on existing code; copy-pasting an entity and missing one setter.

Related errors


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