dotnet/maui · error · BuildException
XC0004
XC0004
Error message
Missing default constructor for "{0}". What it means
XC0004 ConstructorDefaultMissing thrown by RDSourceTypeConverter.CreateResourceDictionaryType when the type associated with a compiled ResourceDictionary Source has no parameterless constructor. The converter resolves the resource type from the XamlResourceIdAttribute, then checks if any constructor on it has zero parameters. If none exists, the build fails because ResourceDictionary.SetAndCreateSource<T> requires 'new T()'.
Source
Thrown at src/Controls/src/Build.Tasks/CompiledConverters/RDSourceTypeConverter.cs:103
foreach (var instruction in (new UriTypeConverter()).ConvertFromString(value, context, node))
yield return instruction; //the Uri
}
private static IEnumerable<Instruction> CreateResourceDictionaryType(
ILContext context,
ModuleDefinition currentModule,
ModuleDefinition module,
BaseNode node,
ElementNode rdNode,
TypeReference resourceTypeRef,
VariableDefinition uriVarDef)
{
var resourceType = module.ImportReference(resourceTypeRef).Resolve();
// validate that the resourceType has a default ctor
var hasDefaultCtor = resourceType.Methods.Any(md => md.IsConstructor && !md.HasParameters);
if (!hasDefaultCtor)
throw new BuildException(BuildExceptionCode.ConstructorDefaultMissing, node, null, resourceType);
var method = module.ImportMethodReference(
context.Cache,
("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ResourceDictionary"),
methodName: "SetAndCreateSource",
parameterTypes: new[] { ("System", "System", "Uri") });
var genericInstanceMethod = new GenericInstanceMethod(method);
genericInstanceMethod.GenericArguments.Add(resourceType);
// public void rd.SetAndCreateSource<TResourceType>(Uri value)
foreach (var instruction in context.Variables[rdNode].LoadAs(context.Cache, currentModule.GetTypeDefinition(context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "ResourceDictionary")), currentModule))
yield return instruction;
yield return Create(Ldloc, uriVarDef);
yield return Create(Callvirt, currentModule.ImportReference(genericInstanceMethod));
}
private static IEnumerable<Instruction> LoadResourceDictionaryFromSource(View on GitHub (pinned to f377ff1c5e)
Solutions
- Add an explicit public parameterless constructor to the ResourceDictionary subclass.
- Remove or supplement any parameterized-only constructors so 'new T()' is valid.
- Ensure the parameterless constructor is public (not private/internal) so the generated code can call it.
Example fix
// before
public partial class MyResources : ResourceDictionary
{
public MyResources(string theme) { ... }
}
// after
public partial class MyResources : ResourceDictionary
{
public MyResources() { InitializeComponent(); }
public MyResources(string theme) { ... }
} Defensive patterns
Strategy: validation
Validate before calling
// Validate that a ResourceDictionary subclass has a public parameterless constructor
static bool HasDefaultConstructor(Type type)
=> type.GetConstructors()
.Any(c => c.IsPublic && c.GetParameters().Length == 0); Type guard
static bool IsInstantiableResourceDictionary(Type type)
=> typeof(ResourceDictionary).IsAssignableFrom(type)
&& type.GetConstructors().Any(c => c.IsPublic && c.GetParameters().Length == 0); Prevention
- Always keep a public parameterless constructor on ResourceDictionary subclasses.
- The default constructor should call InitializeComponent() for XAML-loaded dictionaries.
- Avoid making the parameterless constructor private or internal.
When it happens
Trigger: A XAML ResourceDictionary code-behind class (e.g. a partial class for a merged dictionary) that defines only parameterized constructors and no implicit default constructor. The class is referenced via Source and the compiler tries to instantiate it at compile time but cannot.
Common situations: Adding a constructor with parameters to a ResourceDictionary subclass without also keeping a parameterless one. The default constructor was removed or made private. Using a class that inherits from ResourceDictionary but whose base requires arguments.
Related errors
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/e0527b1a460a5156.
Report an issue: GitHub.