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
- Read the exception message for the exact property name, then set that property on the entity before sending.
- Use the generated domain client's typed options classes so the compiler/intellisense surfaces required fields at design time.
- Add a unit test that constructs each entity you send and asserts no DevToolsClientException on serialisation.
- 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
- Use generated typed options classes so required fields are visible at design time
- Add a serialisation smoke test per DevTools command you send
- Diff DevTools domain entities after a CefSharp upgrade for newly-required fields
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
- Not currently supported.
- IBrowser
- Unable to add MessageId {0} to queuedCommandResults Concurre
- Unable to invoke ExecuteDevToolsMethod on CEF UI Thread.
- Failed to execute dev tools method {0}.
AI-assisted analysis of cefsharp/CefSharp@16bc6e0711 (2026-08-13).
Data as JSON: /api/errors/5c0f4dcfb61403a4.
Report an issue: GitHub.