XINCGer/Unity3DTraining · error · ArgumentException
FieldDescriptors can only be compared to other…
Error message
FieldDescriptors can only be compared to other FieldDescriptors for fields of the same message type.
What it means
FieldDescriptor.CompareTo orders fields by field number, but only fields of the SAME message type have a meaningful order. If the other descriptor belongs to a different containing type, it throws ArgumentException. It exists so fields can be sorted (e.g. for reflection-based serialization order).
Solutions
- Group descriptors by ContainingType and only sort within one message type.
- Use FieldNumber for ordering instead of CompareTo when comparing across types.
- Guard the comparison with a ContainingType equality check before calling CompareTo.
Example fix
// before
list.Sort((a, b) => a.CompareTo(b)); // mixed types
// after
list.Sort((a, b) => a.ContainingType == b.ContainingType
? a.FieldNumber.CompareTo(b.FieldNumber)
: string.CompareOrdinal(a.ContainingType.FullName, b.ContainingType.FullName)); Defensive patterns
Strategy: type-guard
Validate before calling
if (a.ContainingType != b.ContainingType)
throw new InvalidOperationException("Cannot CompareTo fields of different message types"); Type guard
bool SameMessage(a, b) => ReferenceEquals(a.ContainingType, b.ContainingType);
Try / catch
int cmp;
try { cmp = a.CompareTo(b); }
catch (ArgumentException) { cmp = string.CompareOrdinal(a.ContainingType.FullName, b.ContainingType.FullName); } Prevention
- Sort fields per message type, never in one global list.
- Prefer comparing FieldNumber directly for cross-type ordering.
- Group descriptors by ContainingType.FullName in reflection utilities.
When it happens
Trigger: Calling fieldDescriptor1.CompareTo(fieldDescriptor2) where the two descriptors have different ContainingType references, e.g. sorting a mixed list built from two message types, or comparing a field of message A with one of message B.
Common situations: Reflection code that collects FieldDescriptors across multiple message types into one list and sorts it; dictionary/set comparisons relying on IComparable across message types.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- EnumType is only valid for enum fields.
- MessageType is only valid for message fields.
- Field with message or enum type missing type_name.
- Property not found in
- Invalid public dependency
AI-assisted analysis of XINCGer/Unity3DTraining@016f98412e (2026-09-12).
Data as JSON: /api/errors/7dd0fca54230fdbd.
Report an issue: GitHub.
Appendix: source
Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/Reflection/FieldDescriptor.cs:258
public int FieldNumber
{
get
{
return Proto.Number;
}
}
/// <summary>
/// Compares this descriptor with another one, ordering in "canonical" order
/// which simply means ascending order by field number. <paramref name="other"/>
/// must be a field of the same type, i.e. the <see cref="ContainingType"/> of
/// both fields must be the same.
/// </summary>
public int CompareTo(FieldDescriptor other)
{
if (other.ContainingType != ContainingType)
{
throw new ArgumentException("FieldDescriptors can only be compared to other FieldDescriptors " +
"for fields of the same message type.");
}
return FieldNumber - other.FieldNumber;
}
/// <summary>
/// For enum fields, returns the field's type.
/// </summary>
public EnumDescriptor EnumType
{
get
{
if (fieldType != FieldType.Enum)
{
throw new InvalidOperationException("EnumType is only valid for enum fields.");
}
return enumType;
}View on GitHub (pinned to 016f98412e)