AvaloniaUI/Avalonia · error · InvalidOperationException
Expected control '{name}' to be '{typeof(T)} but it was '{re
Error message
Expected control '{name}' to be '{typeof(T)} but it was '{result.GetType()}'. What it means
Thrown by NameScopeExtensions.Find<T>(INameScope, string) when a control with the requested name exists in the scope but is not assignable to the requested generic type T. Find<T> returns null when nothing is found, but treats a type mismatch as a programming error.
Source
Thrown at src/Avalonia.Base/Controls/NameScopeExtensions.cs:38
public static T? Find<T>(this INameScope nameScope, string name)
where T : class
{
_ = nameScope ?? throw new ArgumentNullException(nameof(nameScope));
_ = name ?? throw new ArgumentNullException(nameof(name));
var result = nameScope.Find(name);
if (result == null)
{
return null;
}
if (result is T typed)
{
return typed;
}
throw new InvalidOperationException(
$"Expected control '{name}' to be '{typeof(T)} but it was '{result.GetType()}'.");
}
/// <summary>
/// Finds a named element in an <see cref="INameScope"/>.
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="anchor">The control to take the name scope from.</param>
/// <param name="name">The name.</param>
/// <returns>The named element or null if not found.</returns>
public static T? Find<T>(this ILogical anchor, string name)
where T : class
{
_ = anchor ?? throw new ArgumentNullException(nameof(anchor));
_ = name ?? throw new ArgumentNullException(nameof(name));
var styledAnchor = anchor as StyledElement;
if (styledAnchor == null)
return null;View on GitHub (pinned to 11c5427268)
Solutions
- Align the generic type parameter with the actual registered control type in XAML.
- If you are unsure of the type, use the non-generic Find(name) and check/cast manually.
- If the control type genuinely varies, use Find<object> or Find<IControl> and narrow at runtime.
Example fix
// before
var box = nameScope.Find<TextBox>("myLabel"); // throws, it's a Label
// after
var label = nameScope.Find<Label>("myLabel"); Defensive patterns
Strategy: type-guard
Validate before calling
var found = nameScope.Find(name); if (found is T typed) return typed; return null; // or handle the type mismatch explicitly
Type guard
static T? SafeFind<T>(INameScope scope, string name) where T : class
{
var found = scope.Find(name);
return found as T; // null if wrong type, no throw
} Try / catch
try { return nameScope.Find<T>(name); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Expected control"))
{ return null; } Prevention
- Keep the generic Find<T> type parameter in sync with the XAML control type.
- Prefer Find(name) + 'is T' pattern when the type is uncertain.
- When refactoring a XAML control type, grep for matching Find<T> calls.
When it happens
Trigger: Calling nameScope.Find<TextBox>("myButton") where "myButton" is registered as a Button. The name resolves but result is T fails.
Common situations: XAML x:Name was changed to a different control type but the C# Find<T> call was not updated. Refactoring a view swapped a control type (e.g., TextBlock to Label) while Find<T> still requests the old type. Generic type inference picks the wrong T.
Related errors
- Control with the name '{name}' already registered.
- NameScope is completed, no further registrations are allowed
- Could not find control '{name}'.
- The control doesn't have an associated name scope, probably
- Cannot create ElementName binding when NameScope is null
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/97b73b0f8138a9a2.
Report an issue: GitHub.