dotnet/wpf · error · ArgumentException
SR.NameScopeInvalidIdentifierName
Error message
SR.NameScopeInvalidIdentifierName
What it means
NameScope.RegisterName throws ArgumentException(SR.NameScopeInvalidIdentifierName) when the name is non-empty but is not a valid XAML identifier (per NameValidationHelper.IsValidIdentifierName). XAML names must follow identifier rules (e.g. start with a letter or underscore, no invalid characters).
Solutions
- Sanitize the name with NameValidationHelper.IsValidIdentifierName (or equivalent regex like ^[A-Za-z_][\w]*$) before registering.
- Strip or replace invalid characters programmatically before calling RegisterName.
- Prefix with a letter/underscore when the name starts with a digit.
- Catch ArgumentException and surface a user-facing 'invalid name' message.
Example fix
// before
scope.RegisterName(userText, element); // userText = "my control"
// after
var safe = new string(userText.Where(char.IsLetterOrDigit).ToArray());
if (safe.Length > 0 && !char.IsDigit(safe[0]))
scope.RegisterName(safe, element); Defensive patterns
Strategy: validation
Validate before calling
bool valid = !string.IsNullOrEmpty(name) && System.Text.RegularExpressions.Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$");
Type guard
static bool IsValidXamlName(string name) => !string.IsNullOrEmpty(name) && System.Text.RegularExpressions.Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$");
Try / catch
try { scope.RegisterName(name, element); }
catch (ArgumentException ex) { /* name is not a valid XAML identifier */ } Prevention
- Sanitize user/file-derived strings before using them as XAML names.
- Remember XAML identifier rules: start with letter/underscore, letters/digits/underscores only.
- Add a name-format unit test for any name-generating code.
When it happens
Trigger: Calling RegisterName with names containing spaces, dots, digits at the start, or other non-identifier characters (e.g. "my control", "1stItem", "a-b").
Common situations: Using user-entered text or file names as element names; constructing names by concatenation with delimiters; localized strings used as names; porting WinForms control names that allow characters XAML disallows.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- SR.Format(SR.CannotHavePropertyInTemplate…
- SR.Format(SR.NameNotFound, propertyValue.ChildName)
- SR.Format(SR.NameScopeDuplicateNamesNotAllowed, childName)
- SR.Format(SR.NameScopeNotFound, name, "register")
- SR.Format(SR.NameScopeNotFound, name, "register")
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/cecdc55fcce3814b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/NameScope.cs:46
{
#region INameScope
/// <summary>
/// Register Name-Object Map
/// </summary>
/// <param name="name">name to be registered</param>
/// <param name="scopedElement">object mapped to name</param>
public void RegisterName(string name, object scopedElement)
{
ArgumentNullException.ThrowIfNull(name);
ArgumentNullException.ThrowIfNull(scopedElement);
if (name.Length == 0)
throw new ArgumentException(SR.NameScopeNameNotEmptyString);
if (!NameValidationHelper.IsValidIdentifierName(name))
{
throw new ArgumentException(SR.Format(SR.NameScopeInvalidIdentifierName, name));
}
if (_nameMap == null)
{
_nameMap = new HybridDictionary();
_nameMap[name] = scopedElement;
}
else
{
object nameContext = _nameMap[name];
// first time adding the Name, set it
if (nameContext == null)
{
_nameMap[name] = scopedElement;
}
else if (scopedElement != nameContext)
{
throw new ArgumentException(SR.Format(SR.NameScopeDuplicateNamesNotAllowed, name));View on GitHub (pinned to 81131a70a4)