XINCGer/Unity3DTraining · error · InvalidOperationException

Type registry has no descriptor for type name '

Error message

Type registry has no descriptor for type name '

What it means

JsonFormatter.WriteAny throws InvalidOperationException when formatting a google.protobuf.Any whose embedded type name cannot be resolved in the formatter's TypeRegistry. The Any payload cannot be parsed without the descriptor for the wrapped message.

Solutions

  1. Build the formatter with JsonFormatter.Default.Settings.WithTypeRegistry(TypeRegistry.FromFiles(...all descriptor files...))
  2. Add the descriptor of the Any's inner type to the registry
  3. Use TypeRegistry.FromMessages<T1,T2,...> covering all types embedded in Any fields
  4. Ensure the registry includes dependencies of the wrapped message

Example fix

// before
var formatter = new JsonFormatter(JsonFormatter.Default.Settings);
// after
var settings = JsonFormatter.Default.Settings.WithTypeRegistry(TypeRegistry.FromMessages<MyWrappedMessage>());
var formatter = new JsonFormatter(settings);
Defensive patterns

Strategy: validation

Validate before calling

var typeName = Any.GetTypeName(any.TypeUrl);
if (settings.TypeRegistry.Find(typeName) == null) { throw new InvalidOperationException($"Unregistered Any type: {typeName}"); }

Type guard

bool IsRegistered(JsonFormatter.Settings s, Any a) => s.TypeRegistry.Find(Any.GetTypeName(a.TypeUrl)) != null;

Try / catch

try { json = formatter.Format(msg); } catch (InvalidOperationException ex) when (ex.Message.Contains("Type registry has no descriptor")) { /* register type or skip Any formatting */ }

Prevention

When it happens

Trigger: Formatting a message containing an Any field whose type_url references a message type that was never added to JsonFormatter.Settings.WithTypeRegistry(...); parsing bytes of an unknown packed type.

Common situations: Cross-project Any usage where the receiving side never registered the sender's descriptor types; multi-package protos with only part of the descriptor set registered; plugin-generated types not passed to the registry.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

            var paths = (IList<string>)value.Descriptor.Fields[FieldMask.PathsFieldNumber].Accessor.GetValue(value);
            writer.Write(FieldMask.ToJson(paths, DiagnosticOnly));
        }

        private void WriteAny(TextWriter writer, IMessage value)
        {
            if (DiagnosticOnly)
            {
                WriteDiagnosticOnlyAny(writer, value);
                return;
            }

            string typeUrl = (string)value.Descriptor.Fields[Any.TypeUrlFieldNumber].Accessor.GetValue(value);
            ByteString data = (ByteString)value.Descriptor.Fields[Any.ValueFieldNumber].Accessor.GetValue(value);
            string typeName = Any.GetTypeName(typeUrl);
            MessageDescriptor descriptor = settings.TypeRegistry.Find(typeName);
            if (descriptor == null)
            {
                throw new InvalidOperationException("Type registry has no descriptor for type name '" + typeName + "'");
            }
            IMessage message = descriptor.Parser.ParseFrom(data);
            writer.Write("{ ");
            WriteString(writer, AnyTypeUrlField);
            writer.Write(NameValueSeparator);
            WriteString(writer, typeUrl);

            if (descriptor.IsWellKnownType)
            {
                writer.Write(PropertySeparator);
                WriteString(writer, AnyWellKnownTypeValueField);
                writer.Write(NameValueSeparator);
                WriteWellKnownTypeValue(writer, descriptor, message);
            }
            else
            {
                WriteMessageFields(writer, message, true);
            }

View on GitHub (pinned to 016f98412e)