{"record":{"id":"5c0f4dcfb61403a4","repo":"cefsharp/CefSharp","slug":"prop-name-is-required","errorCode":null,"errorMessage":"{prop.Name} is required","messagePattern":"(.+?) is required","errorType":"validation","errorClass":"DevToolsClientException","httpStatus":null,"severity":"error","filePath":"CefSharp.Core/DevTools/DevToolsDomainEntityBase.cs","lineNumber":155,"sourceCode":"\n            foreach (var prop in properties)\n            {\n                var propertyAttribute = (System.Text.Json.Serialization.JsonPropertyNameAttribute)Attribute.GetCustomAttribute(prop, typeof(System.Text.Json.Serialization.JsonPropertyNameAttribute), false);\n\n                //Only add members that have JsonPropertyNameAttribute\n                if (propertyAttribute == null)\n                {\n                    continue;\n                }\n\n                var propertyName = propertyAttribute.Name;\n                var propertyRequired = Attribute.IsDefined(prop, typeof(System.Diagnostics.CodeAnalysis.DisallowNullAttribute));\n                \n                var propertyValue = prop.GetValue(this);\n\n                if (propertyRequired && propertyValue == null)\n                {\n                    throw new DevToolsClientException(prop.Name + \" is required\");\n                }\n\n                //Not required and value null, don't add to dictionary\n                if (propertyValue == null)\n                {\n                    continue;\n                }\n\n                var propertyValueType = propertyValue.GetType();\n\n                if (typeof(DevToolsDomainEntityBase).IsAssignableFrom(propertyValueType))\n                {\n                    propertyValue = ((DevToolsDomainEntityBase)(propertyValue)).ToDictionary();\n                }\n                else if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(IList<>) && typeof(DevToolsDomainEntityBase).IsAssignableFrom(prop.PropertyType.GetGenericArguments()[0]))\n                {\n                    var values = new List<IDictionary<string, object>>();\n                    foreach (var value in (IEnumerable)propertyValue)","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/cefsharp/CefSharp/blob/16bc6e0711a4945be17e8bc4bc7ccf9469f3fdec/CefSharp.Core/DevTools/DevToolsDomainEntityBase.cs#L137-L173","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvar cmd = new SomeDomainRequest { Url = url }; // 'Transition' is required -> throws\nawait client.SomeDomain.ExecuteAsync(cmd);\n\n// after\nvar cmd = new SomeDomainRequest { Url = url, Transition = \"reload\" };\nawait client.SomeDomain.ExecuteAsync(cmd);","handlingStrategy":"validation","validationCode":"// Validate required (DisallowNull) members before serialising.\nstatic void AssertRequired(object entity)\n{\n    foreach (var p in entity.GetType().GetProperties())\n        if (Attribute.IsDefined(p, typeof(System.Diagnostics.CodeAnalysis.DisallowNullAttribute)) && p.GetValue(entity) == null)\n            throw new InvalidOperationException($\"{p.Name} is required\");\n}","typeGuard":"public static bool HasAllRequired(object entity) =>\n    entity.GetType().GetProperties()\n        .Where(p => Attribute.IsDefined(p, typeof(System.Diagnostics.CodeAnalysis.DisallowNullAttribute)))\n        .All(p => p.GetValue(entity) != null);","tryCatchPattern":"try { await client.SomeDomain.ExecuteAsync(req); }\ncatch (DevToolsClientException ex) when (ex.Message.EndsWith(\" is required\"))\n{ /* set the named property and retry */ }","preventionTips":["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"],"tags":["csharp","cefsharp","devtools","serialization","validation","required-field"],"backgroundTag":null,"analyzedSha":"16bc6e0711a4945be17e8bc4bc7ccf9469f3fdec","analyzedAt":"2026-08-13T19:57:05.828Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}