ppy/osu · warning · InvalidOperationException
Attempting to use this setter will not work correctly. Use s
Error message
Attempting to use this setter will not work correctly. Use specific init-only properties exposed by {nameof(LegacySpriteText)} instead. What it means
Thrown by the Font setter on LegacySpriteText, which is intentionally shadowed (new) to hard-block callers from using the inherited SpriteText.Font property. LegacySpriteText derives its font entirely from the LegacyFont passed to its constructor plus its init-only properties, so the inherited setter would silently do nothing useful.
Source
Thrown at osu.Game/Skinning/LegacySpriteText.cs:38
public const char PP_SUFFIX_CHAR = '\uebd9';
public Vector2? MaxSizePerGlyph { get; init; }
public bool FixedWidth { get; init; }
private readonly LegacyFont font;
private LegacyGlyphStore glyphStore = null!;
protected override char FixedWidthReferenceCharacter => '5';
protected override char[] FixedWidthExcludeCharacters => new[] { ',', '.', '%', 'x', PP_SUFFIX_CHAR };
// ReSharper disable once UnusedMember.Global
// being unused is the point here
public new FontUsage Font
{
get => base.Font;
set => throw new InvalidOperationException(@"Attempting to use this setter will not work correctly. "
+ $@"Use specific init-only properties exposed by {nameof(LegacySpriteText)} instead.");
}
public LegacySpriteText(LegacyFont font)
{
this.font = font;
Shadow = false;
UseFullGlyphHeight = false;
}
[BackgroundDependencyLoader]
private void load(ISkinSource skin)
{
string fontPrefix = skin.GetFontPrefix(font);
base.Font = new FontUsage(fontPrefix, 1, fixedWidth: FixedWidth);
Spacing = new Vector2(-skin.GetFontOverlap(font), 0);
View on GitHub (pinned to d9c73e12ad)
Solutions
- Do not set Font on LegacySpriteText; instead set its init-only properties (FontFace, Size, etc.) or construct it with the correct LegacyFont.
- Type-check before applying a generic Font: if (text is LegacySpriteText lst) { /* use init-only props */ } else { text.Font = font; }.
- Refactor generic font appliers to go through an abstraction that LegacySpriteText implements differently.
Example fix
// before
text.Font = new FontUsage("Arial", 20f);
// after (LegacySpriteText)
var lst = (LegacySpriteText)text;
// configure via constructor or init-only props, e.g.:
lst.Size = 20f; // or whatever init-only property applies Defensive patterns
Strategy: type-guard
Validate before calling
if (text is LegacySpriteText)
throw new InvalidOperationException("LegacySpriteText does not accept Font setter; use init-only props."); Type guard
static bool IsLegacySpriteText(SpriteText t) => t is LegacySpriteText;
Try / catch
try { text.Font = font; }
catch (InvalidOperationException) { /* apply via legacy-specific path */ } Prevention
- Type-check SpriteText before applying a generic Font.
- Configure LegacySpriteText via constructor/init-only properties only.
- Drive font configuration through an abstraction LegacySpriteText implements differently.
When it happens
Trigger: Calling spriteText.Font = new FontUsage(...) on a LegacySpriteText instance, or via XAML/builder code that sets the inherited Font property generically.
Common situations: Generic code that sets Font on any SpriteText (e.g. a style applier) running against a LegacySpriteText; porting component code from SpriteText to LegacySpriteText without updating the font configuration.
Related errors
- A {nameof(PoolableSkinnableSample)} cannot be applied multip
- Setting {nameof(CurrentSkin)}'s value directly is not suppor
- Attempting to add a new component to a target container whic
- Attempting to remove a new component from a target container
- Invalid component type: {component}
AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13).
Data as JSON: /api/errors/6d75dd694c1569c7.
Report an issue: GitHub.