BCUninstaller/Bulk-Crap-Uninstaller · error · InvalidOperationException
Resource of this type doesn't contain specified property
Error message
Resource of this type doesn't contain specified property
What it means
Thrown by LocalisedNameAttribute.GetName() when both ResourceType and ResourceName are set but ResourceType.GetProperty(ResourceName, Public|NonPublic|Static) returns null. That means the named resource entry does not exist on the referenced resource (RESX-generated) class, so the attribute cannot resolve a display string and raises InvalidOperationException.
Source
Thrown at source/KlocTools/Localising/LocalisedNameAttribute.cs:42
ResourceType = resourceType;
}
private string NameOverride { get; }
private string ResourceName { get; }
private Type ResourceType { get; }
public string GetName()
{
if (NameOverride != null)
return NameOverride;
if ((ResourceType != null) && (ResourceName != null))
{
var property = ResourceType.GetProperty(ResourceName,
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
if (property == null)
{
throw new InvalidOperationException("Resource of this type doesn\'t contain specified property");
}
if (property.PropertyType != typeof (string))
{
throw new InvalidOperationException("Specified property is not of string type");
}
return (string) property.GetValue(null, null);
}
return string.Empty;
}
}
}View on GitHub (pinned to 608321de98)
Solutions
- Open the referenced .resx and add the missing key named exactly as ResourceName (case-sensitive).
- Correct the ResourceName spelling / casing to match an existing static string property on ResourceType.
- Point ResourceType at the resource class that actually owns the key, and rebuild so the RESX designer regenerates the property.
Example fix
// before
[LocalisedName(ResourceType = typeof(Strings), ResourceName = "UsrName")]
public string UserName { get; set; } // Strings has no "UsrName"
// after (match the RESX key exactly)
[LocalisedName(ResourceType = typeof(Strings), ResourceName = "UserName")] Defensive patterns
Strategy: validation
Validate before calling
// Verify the resource key exists at startup
var prop = typeof(Strings).GetProperty(keyName,
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
if (prop == null) logger.Error($"Missing resource key {keyName}"); Type guard
static bool ResourceKeyExists(Type resType, string key)
=> resType.GetProperty(key, BindingFlags.Public | BindingFlags.Static) != null; Try / catch
try { attr.GetName(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("doesn't contain"))
{ /* fall back to member.Name, and log the missing key */ } Prevention
- Run a startup self-check that every LocalisedName ResourceName resolves on its ResourceType.
- Gate RESX renames/deletes behind a find-usages sweep over attributes.
- Keep resource key spelling consistent with a unit test that enumerates decorated members.
When it happens
Trigger: Decorating a member with [LocalisedName(ResourceType = typeof(MyResources), ResourceName = "MissingKey")] where "MissingKey" is not a static string property on MyResources (typo, key deleted, wrong resource class, or resource not compiled).
Common situations: Renaming or deleting a RESX entry without updating attributes, pointing ResourceType at the wrong resource class, namespace/resx generation disabled, or splitting resources across assemblies without setting InternalVisibleTo.
Related errors
- Selector is invalid, it has to be in format x => x.Property
- Specified property is not of string type
- Minimum value must be lower than or equal to the maximum val
- Font size must be higher than 0
- Could not find the parent form
AI-assisted analysis of BCUninstaller/Bulk-Crap-Uninstaller@608321de98 (2026-08-13).
Data as JSON: /api/errors/2e164db5141f582f.
Report an issue: GitHub.