reactiveui/refit · error · JsonException

Enum {typeof(TEnum)} does not use a signed backing type.

Error message

Enum {typeof(TEnum)} does not use a signed backing type.

What it means

Thrown by EnumHelpers.ToInt64 when converting an enum value to a signed 64-bit number but the enum's underlying type is unsigned (byte/ushort/uint/ulong), which has no lossless signed representation in that path. The switch only covers the signed TypeCodes; an unsigned enum falls to the default arm.

Source

Thrown at src/Refit/EnumHelpers.cs:150

                writer.WriteNumberValue(ToUInt64(value));
                return;
            }

            writer.WriteNumberValue(ToInt64(value));
        }

        /// <summary>Converts an enum value to a signed 64-bit number without boxing.</summary>
        /// <param name="value">The enum value.</param>
        /// <returns>The signed numeric value.</returns>
        /// <exception cref="JsonException"><typeparamref name="TEnum"/> is backed by an unsigned type, so it has no signed representation.</exception>
        internal static long ToInt64(TEnum value) =>
            _underlyingTypeCode switch
            {
                TypeCode.SByte => Unsafe.As<TEnum, sbyte>(ref value),
                TypeCode.Int16 => Unsafe.As<TEnum, short>(ref value),
                TypeCode.Int32 => Unsafe.As<TEnum, int>(ref value),
                TypeCode.Int64 => Unsafe.As<TEnum, long>(ref value),
                _ => throw new JsonException($"Enum {typeof(TEnum)} does not use a signed backing type.")
            };

        /// <summary>Converts an enum value to an unsigned 64-bit number without boxing.</summary>
        /// <param name="value">The enum value.</param>
        /// <returns>The unsigned numeric value.</returns>
        /// <exception cref="JsonException"><typeparamref name="TEnum"/> is backed by a signed type, so it has no unsigned representation.</exception>
        internal static ulong ToUInt64(TEnum value) =>
            _underlyingTypeCode switch
            {
                TypeCode.Byte => Unsafe.As<TEnum, byte>(ref value),
                TypeCode.UInt16 => Unsafe.As<TEnum, ushort>(ref value),
                TypeCode.UInt32 => Unsafe.As<TEnum, uint>(ref value),
                TypeCode.UInt64 => Unsafe.As<TEnum, ulong>(ref value),
                _ => throw new JsonException($"Enum {typeof(TEnum)} does not use an unsigned backing type.")
            };

        /// <summary>Converts a numeric backing value to the enum type without boxing.</summary>
        /// <typeparam name="TUnderlying">The enum backing value type.</typeparam>

View on GitHub (pinned to b455f65ecc)

Solutions

  1. Do not call ToInt64 on an unsigned-backed enum — use ToUInt64, or check EnumHelpers.IsUnsignedBackingType first.
  2. If encountered through normal use (no custom EnumHelpers usage), report it as a Refit internal bug with the enum definition.
  3. Consider switching the enum to a signed underlying type if a signed numeric form is genuinely required.

Example fix

// before — calling the signedness-mismatched helper on a ulong enum
public enum Flags : ulong { A, B }
long v = EnumHelpers.Info<Flags>.ToInt64(flags); // throws

// after — use the matching unsigned helper
ulong v = EnumHelpers.Info<Flags>.ToUInt64(flags);
Defensive patterns

Strategy: validation

Validate before calling

// Route by signedness instead of assuming a signed representation exists.
static long SafeToInt64<TEnum>(TEnum value) where TEnum : struct, Enum =>
    EnumHelpers.Info<TEnum>.IsUnsignedBackingType(EnumHelpers.Info<TEnum>.UnderlyingTypeCode)
        ? throw new InvalidOperationException("Enum is unsigned; use ToUInt64.")
        : EnumHelpers.Info<TEnum>.ToInt64(value);

Prevention

When it happens

Trigger: ToInt64 is invoked for an enum whose underlying type is unsigned (e.g. enum E : ulong). This is an internal serialization-path method; a well-formed caller would route unsigned enums through ToUInt64 instead. Reaching the throw means the wrong signedness helper was selected for the enum.

Common situations: Effectively unreachable through normal Refit usage because the serialization code checks IsUnsignedBackingType and calls the matching helper. It can surface only if custom code calls EnumHelpers.Info<TEnum>.ToInt64 directly on an unsigned-backed enum, or due to an internal bug.

Related errors


AI-assisted analysis of reactiveui/refit@b455f65ecc (2026-08-13). Data as JSON: /api/errors/6abc624b0b2d7aca. Report an issue: GitHub.