{"record":{"id":"49511f8df21cbdf5","repo":"LuckyPennySoftware/AutoMapper","slug":"expression-lambdaexpression-must-resolve-to-to","errorCode":null,"errorMessage":"Expression '{lambdaExpression}' must resolve to top-level member and not any child object's properties. You can use ForPath, a custom resolver on the child type or the AfterMap option instead.","messagePattern":"Expression '(.+?)' must resolve to top-level member and not any child object's properties\\. You can use ForPath, a custom resolver on the child type or the AfterMap option instead\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/AutoMapper/Internal/ReflectionHelper.cs","lineNumber":98,"sourceCode":"            }\n        }\n        return members;\n        static Type GetCurrentType(Type type) => type.IsGenericType && type.IsCollection() ? type.GenericTypeArguments[0] : type;\n    }\n    public static MemberInfo FindProperty(LambdaExpression lambdaExpression)\n    {\n        Expression expressionToCheck = lambdaExpression.Body;\n        while (true)\n        {\n            switch (expressionToCheck)\n            {\n                case MemberExpression { Member: var member, Expression.NodeType: ExpressionType.Parameter or ExpressionType.Convert }:\n                    return member;\n                case UnaryExpression { Operand: var operand }:\n                    expressionToCheck = operand;\n                    break;\n                default:\n                    throw new ArgumentException(\n                        $\"Expression '{lambdaExpression}' must resolve to top-level member and not any child object's properties. You can use ForPath, a custom resolver on the child type or the AfterMap option instead.\",\n                        nameof(lambdaExpression));\n            }\n        }\n    }\n    public static Type GetMemberType(this MemberInfo member) => member switch\n    {\n        PropertyInfo property => property.PropertyType,\n        MethodInfo method => method.ReturnType,\n        FieldInfo field => field.FieldType,\n        null => throw new System.ArgumentNullException(nameof(member)),\n        _ => throw new ArgumentOutOfRangeException(nameof(member))\n    };\n}","sourceCodeStart":80,"sourceCodeEnd":112,"githubUrl":"https://github.com/LuckyPennySoftware/AutoMapper/blob/dfa6dd587c5854b4beee5934beb39ba6e9569b84/src/AutoMapper/Internal/ReflectionHelper.cs#L80-L112","documentation":"Thrown by ReflectionHelper.FindProperty when a lambda passed to ForMember (or ForSourceMember) does not resolve to a single top-level property or field of the lambda parameter. The method walks the expression body; it accepts only a MemberExpression whose Expression is the parameter (or a UnaryExpression wrapping one). Any nested access like d => d.Child.Property falls through to the default arm. The message explicitly suggests using ForPath, a custom resolver, or AfterMap instead.","triggerScenarios":"Calling .ForMember(d => d.Child.Property, opt => ...) to map into a nested destination property. ForMember only accepts top-level members of TDestination.","commonSituations":"Trying to flatten or un-flatten into a nested destination object; confusing ForMember (flat) with ForPath (nested path); migrating from manual mapping to AutoMapper and attempting nested writes.","solutions":["Use ForPath(d => d.Child.Property, opt => opt.MapFrom(s => s.SourceProp)) for nested destination paths.","Use a custom IValueResolver on the child type's map to set the nested property.","Use AfterMap to imperatively set nested destination properties after mapping."],"exampleFix":"// before — nested access in ForMember\nCreateMap<Source, Dest>()\n    .ForMember(d => d.Address.City, opt => opt.MapFrom(s => s.City));\n\n// after — use ForPath for nested destination\nCreateMap<Source, Dest>()\n    .ForPath(d => d.Address.City, opt => opt.MapFrom(s => s.City));","handlingStrategy":"validation","validationCode":"// Check whether a ForMember lambda is a top-level member access before using it\nstatic bool IsTopLevelMember<TDest, TMember>(Expression<Func<TDest, TMember>> expr)\n{\n    var body = expr.Body;\n    if (body is UnaryExpression u) body = u.Operand;\n    return body is MemberExpression me && me.Expression == expr.Parameters[0];\n}\n// If false, use ForPath instead of ForMember","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use ForMember only for top-level destination properties; use ForPath for nested paths.","Prefer lambda expressions (ForMember(d => d.Prop, ...)) over string-based names for compile-time checking.","Read the error message carefully — it tells you to use ForPath, a custom resolver, or AfterMap."],"tags":["configuration","expression","formember","forpath","nested-mapping"],"backgroundTag":null,"analyzedSha":"dfa6dd587c5854b4beee5934beb39ba6e9569b84","analyzedAt":"2026-08-13T19:56:33.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}