XINCGer/Unity3DTraining · error · InvalidOperationException

Unexpected case in struct field:

Error message

Unexpected case in struct field: 

What it means

JsonFormatter.WriteStructFieldValue throws InvalidOperationException when the Value message's selected oneof field has an unrecognized field number. This is an internal exhaustiveness check: the switch covers the six known Value cases and anything else indicates corrupted or foreign descriptors.

Solutions

  1. Regenerate code and keep the Google.Protobuf NuGet package version aligned with protoc
  2. Do not modify generated descriptors
  3. Verify the message is a genuine google.protobuf.Value, not a similarly named custom type
  4. Upgrade all projects to the same protobuf runtime version
Defensive patterns

Strategy: try-catch

Type guard

static bool IsKnownValueCase(Value v) => v.KindCase == Value.KindOneofCase.NullValue || v.KindCase == Value.KindOneofCase.NumberValue || v.KindCase == Value.KindOneofCase.StringValue || v.KindCase == Value.KindOneofCase.BoolValue || v.KindCase == Value.KindOneofCase.StructValue || v.KindCase == Value.KindOneofCase.ListValue;

Try / catch

try { json = formatter.Format(msg); } catch (InvalidOperationException ex) when (ex.Message.Contains("Unexpected case in struct field")) { /* fix version skew between generated code and runtime */ }

Prevention

When it happens

Trigger: Formatting a Value whose descriptor comes from a mismatched/modified descriptor set so the oneof case resolves to a non-standard field number; mixing generated code with an incompatible Google.Protobuf runtime.

Common situations: Version skew between protoc-generated code and the runtime library; hand-built or rewritten descriptors; binary incompatibility after protobuf schema edits to Value.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of XINCGer/Unity3DTraining@016f98412e (2026-09-12). Data as JSON: /api/errors/041110ae8f118eb5. Report an issue: GitHub.

Appendix: source

Thrown at NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonFormatter.cs:618

            switch (specifiedField.FieldNumber)
            {
                case Value.BoolValueFieldNumber:
                case Value.StringValueFieldNumber:
                case Value.NumberValueFieldNumber:
                    WriteValue(writer, value);
                    return;
                case Value.StructValueFieldNumber:
                case Value.ListValueFieldNumber:
                    // Structs and ListValues are nested messages, and already well-known types.
                    var nestedMessage = (IMessage)specifiedField.Accessor.GetValue(message);
                    WriteWellKnownTypeValue(writer, nestedMessage.Descriptor, nestedMessage);
                    return;
                case Value.NullValueFieldNumber:
                    WriteNull(writer);
                    return;
                default:
                    throw new InvalidOperationException("Unexpected case in struct field: " + specifiedField.FieldNumber);
            }
        }

        internal void WriteList(TextWriter writer, IList list)
        {
            writer.Write("[ ");
            bool first = true;
            foreach (var value in list)
            {
                if (!first)
                {
                    writer.Write(PropertySeparator);
                }
                WriteValue(writer, value);
                first = false;
            }
            writer.Write(first ? "]" : " ]");
        }

View on GitHub (pinned to 016f98412e)