BCUninstaller/Bulk-Crap-Uninstaller · error · ArgumentException

Selector is invalid, it has to be in format x => x.Property

Error message

Selector is invalid, it has to be in format x => x.Property

What it means

Thrown by the instance extension GetLocalisedMemberName<TContainer,TMember>(this TContainer, Expression<Func<TContainer,TMember>> selector). It pattern-matches selector.Body against MemberExpression; anything that is not a direct member access (a property or field reference) is rejected with ArgumentException. The helper exists to extract a LocalisedNameAttribute from a member, so method calls, literals, unary/binary operators, and nested expressions are not valid.

Source

Thrown at source/KlocTools/Localising/LocalisationExtensions.cs:25

using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace Klocman.Localising
{
    public static class LocalisationExtensions
    {
        private static readonly Dictionary<Enum, string> LocalisedEnumNameCache = new();

        /// <summary>
        ///     Get a fancy name of selected property or field
        /// </summary>
        public static string GetLocalisedMemberName<TContainer, TMember>(this TContainer instance,
            Expression<Func<TContainer, TMember>> selector) where TContainer : class
        {
            if (selector.Body is not MemberExpression expression)
                throw new ArgumentException("Selector is invalid, it has to be in format x => x.Property");
            
            var member = expression.Member;
            return GetLocalisedMemberName(member);
        }

        /// <summary>
        ///     Get a fancy name of selected property or field
        /// </summary>
        public static string GetLocalisedMemberName<TContainer, TMember>(Expression<Func<TContainer, TMember>> selector) 
            where TContainer : class
        {
            if (selector.Body is not MemberExpression expression)
                throw new ArgumentException("Selector is invalid, it has to be in format x => x.Property");

            var member = expression.Member;
            return GetLocalisedMemberName(member);
        }

View on GitHub (pinned to 608321de98)

Solutions

  1. Change the selector to a simple property/field access: obj.GetLocalisedMemberName(x => x.PropertyName).
  2. If you need a method's localised name, call the MemberInfo overload GetLocalisedMemberName(MemberInfo) with typeof(T).GetMethod(...).
  3. Extract the member first then pass MemberInfo directly to the MemberInfo overload.

Example fix

// before
var name = obj.GetLocalisedMemberName(x => x.GetDisplayName()); // throws

// after
var name = obj.GetLocalisedMemberName(x => x.DisplayName);
Defensive patterns

Strategy: validation

Validate before calling

// Reject selectors that are not simple member access before calling
if (selector.Body is not MemberExpression)
    throw new InvalidOperationException("Selector must be x => x.Property");
var name = instance.GetLocalisedMemberName(selector);

Type guard

static bool IsMemberSelector<TC, TM>(Expression<Func<TC, TM>> sel)
    => sel.Body is MemberExpression;

Prevention

When it happens

Trigger: Passing a lambda whose body is not a bare member access: x => x.Compute(), x => 42, x => x.Name + x.Suffix, or x => SomeStatic.Property. Only x => x.Property or x => x.Field are accepted.

Common situations: Refactoring a property into a method (x => x.Name becomes x => x.GetName()), pointing the selector at a computed expression while building a localised display name, or copy-pasting a lambda from a LINQ Where clause.

Related errors


AI-assisted analysis of BCUninstaller/Bulk-Crap-Uninstaller@608321de98 (2026-08-13). Data as JSON: /api/errors/4ebf64479257b146. Report an issue: GitHub.