dotnet/wpf · error · ArgumentException
SR.ArgumentRequired
Error message
SR.ArgumentRequired
What it means
The XamlValueConverter(Type, XamlType, name) constructor throws ArgumentException('ArgumentRequired') when all three parameters are null. A value converter must be identifiable by at least one of: its converter CLR type, its target XamlType, or an explicit name — otherwise instances could not be named, cached, or compared (IEquatable). At least one identifier is therefore mandatory.
Solutions
- Pass at least one non-null argument — typically the converter Type or the target XamlType.
- Provide a name when neither type nor target applies so the converter can still be identified.
- Guard the construction site: validate that at least one argument is non-null before constructing.
- Catch ArgumentException at the boundary if inputs come from external configuration and surface a clear config error.
Example fix
// before
var conv = new XamlValueConverter<ValueConverter>(maybeType, maybeTarget, null);
// after
if (maybeType is null && maybeTarget is null) throw new InvalidOperationException("converter requires a type or target");
var conv = new XamlValueConverter<ValueConverter>(maybeType, maybeTarget, null); Defensive patterns
Strategy: validation
Validate before calling
if (converterType is null && targetType is null && name is null) throw new ArgumentException("At least one of converterType/targetType/name is required"); Type guard
static bool ConverterIdentifiable(Type t, XamlType target, string name) => t is not null || target is not null || name is not null;
Try / catch
try { var c = new XamlValueConverter<T>(type, target, name); } catch (ArgumentException ex) { /* all-null converter descriptor */ } Prevention
- Always pass the converter Type or target XamlType when constructing converters.
- Validate configuration-driven converter inputs before construction.
- Supply an explicit name for converter identification when types are unknown.
- Centralize converter construction in one factory that enforces this invariant.
When it happens
Trigger: new XamlValueConverter<TConverterBase>(null, null, null) — e.g. code that conditionally builds converters where every input defaulted to null, or deserialization/constructor plumbing that forgot to pass the converter type or target type.
Common situations: Generic converter-factory code where a config-driven converterType lookup returned null and fallbacks (targetType, name) were also null; refactoring that made previously-supplied arguments optional; unit tests constructing a 'blank' converter.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- SR.Format(SR.MustBeOfType, nameof(value)…
- ArgumentException(SR.Format(SR.CollectionCannotContainNulls…
- ArgumentException(SR.StringIsNullOrEmpty, nameof(fileName))
- ArgumentNullException(nameof(arrayType))
- ArgumentNullException(nameof(clrNamespace))
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/acd7cf18b85d7142.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Schema/XamlValueConverter.cs:33
private TConverterBase _instance;
private ThreeValuedBool _isPublic;
private volatile bool _instanceIsSet; // volatile for the same reason as valid flags in TypeReflector/MemberReflector
public string Name { get; }
public Type ConverterType { get; }
public XamlType TargetType { get; }
public XamlValueConverter(Type converterType, XamlType targetType)
:this(converterType, targetType, null)
{
}
public XamlValueConverter(Type converterType, XamlType targetType, string name)
{
if (converterType is null && targetType is null && name is null)
{
throw new ArgumentException(SR.Format(SR.ArgumentRequired, $"{nameof(converterType)}, {nameof(targetType)}, {nameof(name)}"));
}
ConverterType = converterType;
TargetType = targetType;
Name = name ?? GetDefaultName();
}
public TConverterBase ConverterInstance
{
get
{
if (!_instanceIsSet)
{
Interlocked.CompareExchange(ref _instance, CreateInstance(), null);
_instanceIsSet = true;
}
return _instance;View on GitHub (pinned to 81131a70a4)