JamesNK/Newtonsoft.Json · error · InvalidOperationException

Enum name '{0}' already exists on enum '{1}'.

Error message

Enum name '{0}' already exists on enum '{1}'.

What it means

InitializeValuesAndNames (EnumUtils.cs:52-92) builds the EnumInfo by computing each member's resolved name (from [EnumMember(Value=...)] then the NamingStrategy). It checks for duplicates at EnumUtils.cs:75-78: if an already-seen resolved name collides with the current one, it throws InvalidOperationException naming both the duplicate name and the enum.

Source

Thrown at Src/Newtonsoft.Json/Utilities/EnumUtils.cs:77

            for (int i = 0; i < names.Length; i++)
            {
                string name = names[i];
                FieldInfo f = enumType.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)!;
                values[i] = ToUInt64(f.GetValue(null)!);

                string resolvedName;
#if HAVE_DATA_CONTRACTS
                string? specifiedName = f.GetCustomAttributes(typeof(EnumMemberAttribute), true)
                         .Cast<EnumMemberAttribute>()
                         .Select(a => a.Value)
                         .SingleOrDefault();
                hasSpecifiedName = specifiedName != null;
                resolvedName = specifiedName ?? name;

                if (Array.IndexOf(resolvedNames, resolvedName, 0, i) != -1)
                {
                    throw new InvalidOperationException("Enum name '{0}' already exists on enum '{1}'.".FormatWith(CultureInfo.InvariantCulture, resolvedName, enumType.Name));
                }
#else
                resolvedName = name;
                hasSpecifiedName = false;
#endif

                resolvedNames[i] = key.Value2 != null
                    ? key.Value2.GetPropertyName(resolvedName, hasSpecifiedName)
                    : resolvedName;
            }

            bool isFlags = enumType.IsDefined(typeof(FlagsAttribute), false);

            return new EnumInfo(isFlags, values, names, resolvedNames);
        }

        public static IList<T> GetFlagsValues<T>(T value) where T : struct
        {

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Make every [EnumMember(Value=...)] distinct across the enum.
  2. Adjust the NamingStrategy (or member names) so resolved names stay unique.
  3. Rename the colliding enum members so they differ even after transformation.
  4. Audit enum members after changing the serializer's NamingStrategy.

Example fix

// before
[EnumMember(Value = "active")] Active,
[EnumMember(Value = "active")] ActiveNow, // collision -> throws
// after
[EnumMember(Value = "active")]      Active,
[EnumMember(Value = "active_now")] ActiveNow,
Defensive patterns

Strategy: validation

Validate before calling

// Detect duplicate resolved enum names before serialization at startup.
static void CheckEnumNames(Type enumType, Newtonsoft.Json.Serialization.NamingStrategy? ns) {
    var names = Enum.GetNames(enumType).Select(n => ns != null ? ns.GetPropertyName(n, false) : n);
    if (names.GroupBy(n => n).Any(g => g.Count() > 1)) throw new InvalidOperationException("Duplicate enum resolved names.");
}

Type guard

static bool EnumNamesUnique(Type enumType, Newtonsoft.Json.Serialization.NamingStrategy? ns) => Enum.GetNames(enumType).Select(n => ns != null ? ns.GetPropertyName(n, false) : n).Distinct().Count() == Enum.GetNames(enumType).Length;

Try / catch

try { JsonConvert.SerializeObject(obj, settings); } catch (InvalidOperationException ex) when (ex.Message.Contains("already exists on enum")) { /* fix [EnumMember]/naming strategy */ }

Prevention

When it happens

Trigger: Two enum members resolve to the same serialized name — either via identical [EnumMember(Value="x")] attributes, or because a NamingStrategy (camelCase, snake_case) maps distinct member names onto the same string.

Common situations: Refactoring/renaming enum members that then collide under a naming strategy; copy-paste of [EnumMember(Value=...)] values; switching NamingStrategy (e.g. to SnakeCaseNamingStrategy) causing previously-unique names to collapse.

Related errors


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