dotnet/maui · error · ArgumentException
uniqueName must not contain a .
Error message
uniqueName must not contain a .
What it means
ExportEffectAttribute rejects any uniqueName containing '.', because the runtime resolves effects via the 'ResolutionGroupName.Name' composite and an embedded dot would collide with that scheme or produce an ambiguous id. The constructor (ExportEffectAttribute.cs:22) does an ordinal IndexOf check and throws ArgumentException before storing the id.
Source
Thrown at src/Controls/src/Core/ExportEffectAttribute.cs:22
namespace Microsoft.Maui.Controls
{
#pragma warning disable CS1734 // XML comment on 'ExportEffectAttribute' has a paramref tag for 'effectType', but there is no parameter by that name
/// <summary>Attribute that identifies a <see cref="Microsoft.Maui.Controls.Effect"/> with a unique identifier that can be used with <see cref="M:Microsoft.Maui.Controls.Effect.Resolve(System.String)"/> to locate an effect.</summary>
#pragma warning restore CS1734
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ExportEffectAttribute : Attribute
{
/// <summary>Creates a new <see cref="Microsoft.Maui.Controls.ExportEffectAttribute"/>.</summary>
/// <param name="effectType">The type of the marked <see cref="Microsoft.Maui.Controls.Effect"/>.</param>
/// <param name="uniqueName">A unique name for the <see cref="Microsoft.Maui.Controls.Effect"/>.</param>
/// <remarks>Developers must supply a</remarks>
public ExportEffectAttribute(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type effectType,
string uniqueName)
{
if (uniqueName.IndexOf(".", StringComparison.Ordinal) != -1)
throw new ArgumentException("uniqueName must not contain a .");
Type = effectType;
Id = uniqueName;
}
internal string Id { get; private set; }
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
internal Type Type { get; private set; }
}
}View on GitHub (pinned to f377ff1c5e)
Solutions
- Remove all '.' characters from the uniqueName argument, e.g. use "MyEffect" not "MyCompany.MyEffect".
- Keep the resolution group name on ExportEffect via the separate [assembly: ResolutionGroupName("MyCompany")] attribute; the group and the effect name are concatenated by the runtime.
- If you need namespacing for uniqueness, use camelCase or underscores ("MyCompany_MyEffect") rather than dots.
- Audit every ExportEffect assembly attribute for stray dots after bulk edits.
Example fix
// before
[assembly: ExportEffect(typeof(MyEffect), "Acme.MyEffect")]
// after
[assembly: ResolutionGroupName("Acme")]
[assembly: ExportEffect(typeof(MyEffect), "MyEffect")] Defensive patterns
Strategy: validation
Validate before calling
if (uniqueName.Contains('.')) throw new ArgumentException("uniqueName must not contain '.'"); Prevention
- Define effect names as constants without dots and reference them in the attribute.
- Put the company prefix in ResolutionGroupName, not in the ExportEffect name.
- Add a build-time check or unit test that scans assembly attributes for names containing '.'.
When it happens
Trigger: Decorating an assembly with `[assembly: ExportEffect(typeof(MyEffect), "My.Group.Name")]` or any name containing a period. Also triggered by copy-paste from ExportCell/ExportHandler attributes whose naming conventions differ.
Common situations: Migrating from Xamarin.Forms where names were reused, auto-generating effect attributes from a script that joins segments with '.', or accidentally including a namespace prefix in the uniqueName.
Related errors
- Call to Create<{typeof(TSource)}, {typeof(TProperty)}> could
- Call to Create<{typeof(TSource)}, {typeof(TProperty)}>() was
- Cannot attach Effect to multiple sources
- throw new ArgumentOutOfRangeException();
- Error: Building dotnet-samples with NativeAOT is only suppor
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/62db34a53a865689.
Report an issue: GitHub.