dotnet/wpf · error · ArgumentException
SR.StyleCannotBeBasedOnSelf
Error message
SR.StyleCannotBeBasedOnSelf
What it means
The Style.BasedOn setter throws ArgumentException (SR.StyleCannotBeBasedOnSelf) when a style is assigned as its own BasedOn. This is a degenerate circular-reference case that would produce infinite lookup during style resolution.
Solutions
- Assign a different Style instance as BasedOn; verify the resource key used to fetch the base style is not the style's own key.
- If creating a default-derived style, pass null (leave BasedOn unset) to inherit from the theme default.
- Add a guard comparing references before assignment when base styles are computed dynamically.
Example fix
// before style.BasedOn = style; // circular // after var baseStyle = (Style)resources["BaseButtonStyle"]; if (!ReferenceEquals(baseStyle, style)) style.BasedOn = baseStyle;
Defensive patterns
Strategy: validation
Validate before calling
if (!ReferenceEquals(baseStyle, style)) style.BasedOn = baseStyle; else throw new InvalidOperationException("Style cannot be based on itself"); Type guard
static bool CanBaseOn(Style style, Style baseStyle) => !ReferenceEquals(style, baseStyle);
Try / catch
try { style.BasedOn = candidate; }
catch (ArgumentException ex) when (ex.Message.Contains("based on itself")) { /* resolve the correct base key or leave BasedOn unset */ } Prevention
- Verify resource keys so a style never resolves its own key as its base.
- When computing base styles dynamically, compare references before assignment.
- Model style inheritance chains as a DAG and check for cycles when building them programmatically.
When it happens
Trigger: Executing style.BasedOn = style; — typically via a code path that computes the base style from a dictionary and accidentally selects the same instance (e.g. self-referencing keyed resource lookup).
Common situations: Programmatic style chains where the lookup key resolves back to the same style; refactoring XAML BasedOn={StaticResource SameKey} onto itself; copy-paste of style definitions keeping the same key.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.Format(SR.MustBeFrameworkDerived, value.Name)
- SR.Format(SR.StyleBasedOnHasLoop)
- SR.FlowDocumentScrollViewerDocumentBelongsToAnotherFlowDocum…
- SR.CannotMoveToUnknownPosition
- SR.CircularOwnerChild
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/44557d02548e4d3e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Style.cs:205
return _basedOn;
}
set
{
// Verify Context Access
VerifyAccess();
if (_sealed)
{
throw new InvalidOperationException(SR.Format(SR.CannotChangeAfterSealed, "Style"));
}
if( value == this )
{
// Basing on self is not allowed. This is a degenerate case
// of circular reference chain, the full check for circular
// reference is done in Seal().
throw new ArgumentException(SR.StyleCannotBeBasedOnSelf);
}
_basedOn = value;
SetModified(BasedOnID);
}
}
/// <summary>
/// Visual triggers
/// </summary>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TriggerCollection Triggers
{
get
{
// Verify Context AccessView on GitHub (pinned to 81131a70a4)