{"record":{"id":"769c40668559d8d1","repo":"JamesNK/Newtonsoft.Json","slug":"property-does-not-have-a-getter","errorCode":null,"errorMessage":"Property does not have a getter.","messagePattern":"Property does not have a getter\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Src/Newtonsoft.Json/Utilities/ExpressionReflectionDelegateFactory.cs","lineNumber":241,"sourceCode":"                return () => (T)Activator.CreateInstance(type)!;\n            }\n        }\n\n        [RequiresDynamicCode(MiscellaneousUtils.AotWarning)]\n        public override Func<T, object?> CreateGet<T>(PropertyInfo propertyInfo)\n        {\n            ValidationUtils.ArgumentNotNull(propertyInfo, nameof(propertyInfo));\n\n            Type instanceType = typeof(T);\n            Type resultType = typeof(object);\n\n            ParameterExpression parameterExpression = Expression.Parameter(instanceType, \"instance\");\n            Expression resultExpression;\n\n            MethodInfo? getMethod = propertyInfo.GetGetMethod(true);\n            if (getMethod == null)\n            {\n                throw new ArgumentException(\"Property does not have a getter.\");\n            }\n\n            if (getMethod.IsStatic)\n            {\n                resultExpression = Expression.MakeMemberAccess(null, propertyInfo);\n            }\n            else\n            {\n                Expression readParameter = EnsureCastExpression(parameterExpression, propertyInfo.DeclaringType!);\n\n                resultExpression = Expression.MakeMemberAccess(readParameter, propertyInfo);\n            }\n\n            resultExpression = EnsureCastExpression(resultExpression, resultType);\n\n            LambdaExpression lambdaExpression = Expression.Lambda(typeof(Func<T, object>), resultExpression, parameterExpression);\n\n            Func<T, object?> compiled = (Func<T, object?>)lambdaExpression.Compile();","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/JamesNK/Newtonsoft.Json/blob/4f73e74372445108d2c1bda37b36e6f5e43402e0/Src/Newtonsoft.Json/Utilities/ExpressionReflectionDelegateFactory.cs#L223-L259","documentation":"ExpressionReflectionDelegateFactory.CreateGet<T>(PropertyInfo) (ExpressionReflectionDelegateFactory.cs:228-261) compiles an expression tree to read a property. It calls propertyInfo.GetGetMethod(true); if the property has no get accessor (write-only), it throws ArgumentException at ExpressionReflectionDelegateFactory.cs:241. This is the Expression-based counterpart of the DynamicReflectionDelegateFactory error [251], used on platforms where Expression trees are preferred over ReflectionEmit (non-NET20/35).","triggerScenarios":"The serializer's contract creation attempts to build a getter for a write-only property (only a setter) on a runtime that selects ExpressionReflectionDelegateFactory.","commonSituations":"Write-only properties (set; only); fluent-builder APIs; generated proxies with asymmetric accessors; intent-restricted setters; same root cause as [251] but on a different delegate factory.","solutions":["Add a getter to the property (private getters are accepted because GetGetMethod(true) is used).","Annotate the write-only property with [JsonIgnore] so serialization skips it.","Configure an IContractResolver that excludes properties where !CanRead.","Expose the value through a separate readable member."],"exampleFix":"// before\npublic string Secret { set; } // write-only -> throws on serialize\n// after\n[JsonIgnore]\npublic string Secret { set; }","handlingStrategy":"validation","validationCode":"// Exclude write-only properties from serialization contracts.\nforeach (var prop in type.GetProperties()) {\n    if (prop.GetGetMethod(true) == null) continue; // write-only, skip\n    /* build getter via ExpressionReflectionDelegateFactory */\n}","typeGuard":"static bool HasGetter(System.Reflection.PropertyInfo p) => p.GetGetMethod(true) != null;","tryCatchPattern":"try { serializer.Serialize(writer, value); } catch (ArgumentException ex) when (ex.Message.Contains(\"does not have a getter\")) { /* mark the offending property [JsonIgnore] */ }","preventionTips":["Mark write-only properties with [JsonIgnore].","Use a contract resolver that skips properties where !CanRead.","Add a getter (even a private one) to any property you intend to serialize."],"tags":["reflection","serialization","property","newtonsoft-json"],"analyzedSha":"4f73e74372445108d2c1bda37b36e6f5e43402e0","analyzedAt":"2026-08-07T06:10:08.596Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}