dotnet/maui · error · InvalidOperationException

{nameof(AutomationId)} may only be set one time.

Error message

{nameof(AutomationId)} may only be set one time.

What it means

Element.AutomationId throws InvalidOperationException if set when it already has a non-null value: the setter checks `if (AutomationId != null)` before assigning. Automation IDs are designed to be immutable once assigned (they back test/automation identity), so a second assignment is rejected.

Source

Thrown at src/Controls/src/Core/Element/Element.cs:88

		WeakReference<Element> _parentOverride;

		string _styleId;

		IReadOnlyList<Element> _logicalChildrenReadonly;

		IList<Element> _internalChildren;

		/// <summary>Gets or sets a value that allows the automation framework to find and interact with this element.</summary>
		/// <value>A value that the automation framework can use to find and interact with this element.</value>
		/// <remarks>This value may only be set once on an element.</remarks>
		public string AutomationId
		{
			get { return (string)GetValue(AutomationIdProperty); }
			set
			{
				if (AutomationId != null)
					throw new InvalidOperationException($"{nameof(AutomationId)} may only be set one time.");

				SetValue(AutomationIdProperty, value);
			}
		}

		/// <summary>Gets or sets a value used to identify a collection of semantically similar elements.</summary>
		/// <value>A string that represents the collection the element belongs to.</value>
		/// <remarks>Use the class id property to collect together elements into semantically similar groups for identification in UI testing and in theme engines.</remarks>
		public string ClassId
		{
			get => (string)GetValue(ClassIdProperty);
			set => SetValue(ClassIdProperty, value);
		}

		/// <summary>Gets or sets the styles and properties that will be applied to the element during runtime.</summary>
		/// <value>A collection containing the different <see cref="Effect"/> to be applied to the element.</value>
		public IList<Effect> Effects
		{

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Set AutomationId exactly once per element instance.
  2. If reusing element instances, assign the id only when it is null: `if (el.AutomationId is null) el.AutomationId = id;`.
  3. Move the assignment to a single initialization site and remove duplicates.

Example fix

// before
var el = new Label { AutomationId = "a" };
el.AutomationId = "b"; // throws

// after
var el = new Label { AutomationId = "a" };
if (string.IsNullOrEmpty(el.AutomationId)) el.AutomationId = "b";
Defensive patterns

Strategy: validation

Validate before calling

static void SetAutomationIdOnce(Element el, string id)
{
    if (el.AutomationId is null) el.AutomationId = id;
}

Type guard

static bool CanSetAutomationId(Element el) => el.AutomationId is null;

Prevention

When it happens

Trigger: Setting AutomationId twice on the same Element instance; a binding that re-evaluates and reassigns AutomationId; XAML + code both setting it; Hot Reload re-applying the property.

Common situations: DataTemplates reusing elements where code resets the id; setting AutomationId in a parent and again in a child merge; two code paths (InitializeComponent + later code) both assigning; Hot Reload of XAML re-running the setter.

Related errors


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/449db5b86cef602f. Report an issue: GitHub.