JamesNK/Newtonsoft.Json · error · InvalidOperationException

Could not create getter for {0}. ByRef return values are not

Error message

Could not create getter for {0}. ByRef return values are not supported.

What it means

Thrown by ReflectionDelegateFactory.CreateGet(MemberInfo) when a PropertyInfo's PropertyType.IsByRef is true — the property returns a managed pointer (C# 7 `ref` return). Json.NET's getter delegates return `object`, and a ByRef value cannot be boxed into the delegate pipeline, so it refuses outright. This is a hard design limitation of the reflection delegate factory, not a configuration problem.

Source

Thrown at Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs:48

using Newtonsoft.Json.Serialization;

#if !HAVE_LINQ
using Newtonsoft.Json.Utilities.LinqBridge;
#endif

namespace Newtonsoft.Json.Utilities
{
    internal abstract class ReflectionDelegateFactory
    {
        [RequiresDynamicCode(MiscellaneousUtils.AotWarning)]
        public Func<T, object?> CreateGet<T>(MemberInfo memberInfo)
        {
            if (memberInfo is PropertyInfo propertyInfo)
            {
                // https://github.com/dotnet/corefx/issues/26053
                if (propertyInfo.PropertyType.IsByRef)
                {
                    throw new InvalidOperationException("Could not create getter for {0}. ByRef return values are not supported.".FormatWith(CultureInfo.InvariantCulture, propertyInfo));
                }

                return CreateGet<T>(propertyInfo);
            }

            if (memberInfo is FieldInfo fieldInfo)
            {
                return CreateGet<T>(fieldInfo);
            }

            throw new Exception("Could not create getter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo));
        }

        [RequiresDynamicCode(MiscellaneousUtils.AotWarning)]
        public Action<T, object?> CreateSet<T>(MemberInfo memberInfo)
        {
            if (memberInfo is PropertyInfo propertyInfo)
            {

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Replace the ref-returning property with a regular value-returning property used for serialization.
  2. Annotate the ref-returning property with [JsonIgnore].
  3. Project the type into a plain serializable DTO before serializing (e.g. via LINQ Select).

Example fix

// before
private int _x;
public ref int X => ref _x;

// after
private int _x;
[JsonIgnore]
public ref int X => ref _x;
public int XValue => _x;
Defensive patterns

Strategy: validation

Validate before calling

// Exclude ref-returning properties from serialization candidates.
bool IsSerializableProperty(PropertyInfo p) => !p.PropertyType.IsByRef;

Type guard

static bool IsNotByRefProperty(PropertyInfo p) => !p.PropertyType.IsByRef;

Prevention

When it happens

Trigger: Serializing a type that exposes a property declared `public ref int X => ref _field;` (C# 7+ ref returns). Any code path that calls CreateGet on such a PropertyInfo triggers it — typically the serialization contract builder walking the type's properties.

Common situations: Interop with span-like wrappers or array-backed value-type mutability patterns that expose ref returns, performance-critical code reusing ref-returning properties in a serialization graph, or porting C# 7 code that wasn't designed for serialization.

Related errors


AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07). Data as JSON: /api/errors/2d33ec023c369254. Report an issue: GitHub.