dotnet/maui · error · BuildException
XC0008
XC0008
Error message
No Add() method defined on "{0}{1}". What it means
Thrown for a ListNode (a property populated with multiple child elements) when the property's resolved type exposes no public single-parameter Add method. The compiler needs an Add(T) to emit each child-add call and throws when GetMethods finds none.
Source
Thrown at src/Controls/src/Build.Tasks/SetPropertiesVisitor.cs:188
var parentList = node2;
var parent = Context.Variables[(ElementNode)parentList.Parent];
if (skips.Contains(parentList.XmlName))
return;
if (parentNode is ElementNode node3 && node3.SkipProperties.Contains(propertyName))
return;
var elementType = parent.VariableType;
var localname = parentList.XmlName.LocalName;
Context.IL.Append(GetPropertyValue(parent, parentList.XmlName, Context, node, out TypeReference propertyType));
if (CanAddToResourceDictionary(parent, propertyType, node, node, Context))
{
Context.IL.Append(AddToResourceDictionary(parent, node, node, Context));
return;
}
var adderTuple = propertyType.GetMethods(Context.Cache, md => md.Name == "Add" && md.Parameters.Count == 1, Module).FirstOrDefault() ??
throw new BuildException(AdderMissing, node, null, parent.VariableType, localname);
var adderRef = Module.ImportReference(adderTuple.Item1);
adderRef = Module.ImportReference(adderRef.ResolveGenericParameters(adderTuple.Item2, Module));
Context.IL.Append(vardef.LoadAs(Context.Cache, adderRef.Parameters[0].ParameterType.ResolveGenericParameters(adderRef), Module));
Context.IL.Emit(Callvirt, adderRef);
if (adderRef.ReturnType.FullName != "System.Void")
Context.IL.Emit(Pop);
}
}
public void Visit(RootNode node, INode parentNode)
{
}
public void Visit(ListNode node, INode parentNode)
{
}View on GitHub (pinned to f377ff1c5e)
Solutions
- Make the property type a collection that exposes a public Add(T) (e.g. IList<T>, List<T>, ObservableCollection<T>).
- Ensure the property is initialised to a concrete collection instance.
- If targeting a ResourceDictionary, confirm the entry is in a ResourceDictionary context and has a valid key.
Example fix
// before (no Add)
public string[] Items { get; set; }
// after
public IList<string> Items { get; } = new List<string>(); Defensive patterns
Strategy: validation
Validate before calling
// Ensure the collection property type has a public single-parameter Add
static bool HasAddMethod(Type collectionType)
=> collectionType.GetMethods()
.Any(m => m.Name == "Add" && m.IsPublic && m.GetParameters().Length == 1); Type guard
static bool IsXamlCollection(Type t) =>
typeof(System.Collections.IEnumerable).IsAssignableFrom(t) && HasAddMethod(t); Prevention
- Prefer IList<T>/List<T>/ObservableCollection<T> for XAML-populated properties.
- Initialise collection properties to concrete instances.
- Avoid arrays or read-only interfaces without Add for XAML-bound collections.
When it happens
Trigger: A collection property whose type lacks Add(T) — e.g. the property is an array, a raw IEnumerable, or the type resolved to something unexpected — so `propertyType.GetMethods(... Add, 1 param)` returns null.
Common situations: Property declared as an array or IReadOnlyList without Add; property not initialised; the wrong generic type was resolved; ResourceDictionary path not matching.
Related errors
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/5663fa7f008cec07.
Report an issue: GitHub.