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

  1. Make the property type a collection that exposes a public Add(T) (e.g. IList<T>, List<T>, ObservableCollection<T>).
  2. Ensure the property is initialised to a concrete collection instance.
  3. 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

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.