{"record":{"id":"0bd4c89736adfa49","repo":"egametang/ET","slug":"opcodetype-not-found-opcode-type-fullname","errorCode":null,"errorMessage":"OpcodeType not found opcode: {type.FullName}","messagePattern":"OpcodeType not found opcode: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"Packages/cn.etetet.core/Scripts/Core/Share/Network/OpcodeType.cs","lineNumber":64,"sourceCode":"                    var attrs = type.GetCustomAttributes(typeof (ResponseTypeAttribute), false);\n                    if (attrs.Length == 0)\n                    {\n                        Log.Error($\"not found responseType: {type}\");\n                        continue;\n                    }\n\n                    ResponseTypeAttribute responseTypeAttribute = attrs[0] as ResponseTypeAttribute;\n                    this.requestResponse.Add(type, CodeTypes.Instance.GetType($\"ET.{responseTypeAttribute.Type}\"));\n                }\n            }\n        }\n        \n        public ushort GetOpcode(Type type)\n        {\n            ushort opcode = this.typeOpcode.GetValueByKey(type);\n            if (opcode == 0)\n            {\n                throw new Exception($\"OpcodeType not found opcode: {type.FullName}\");\n            }\n            return opcode;\n        }\n\n        public Type GetType(ushort opcode)\n        {\n            Type type = this.typeOpcode.GetKeyByValue(opcode);\n            if (type == null)\n            {\n                throw new Exception($\"OpcodeType not found type: {opcode}\");\n            }\n            return type;\n        }\n\n        public Type GetResponseType(Type request)\n        {\n            if (!this.requestResponse.TryGetValue(request, out Type response))\n            {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.core/Scripts/Core/Share/Network/OpcodeType.cs#L46-L82","documentation":"OpcodeType.GetOpcode(Type) returns the registered opcode for a message type; a value of 0 means the type was never registered. The framework treats unregistered messages as a fatal serialization contract error.","triggerScenarios":"Sending a message Type that was not scanned by CodeTypes or lacks the message/protocol attributes, or sending a type from an assembly that wasn't loaded at registration time.","commonSituations":"New message class added without [Message]/[ProtoContract] attribute, the assembly not passed to CodeTypes, or hotfix code referencing a type compiled out of the opcode generation.","solutions":["Confirm the type has the message attribute and is in a scanned assembly.","Re-run the Luban/opcode code generation so the opcode table includes the type.","Ensure the message assembly is loaded before OpcodeType initialization."],"exampleFix":"// before\nushort op = OpcodeType.Instance.GetOpcode(typeof(MyNewMessage));\n// after\n// add [Message(...)]; regenerate opcodes; then:\nushort op = OpcodeType.Instance.GetOpcode(typeof(MyNewMessage));","handlingStrategy":"validation","validationCode":"if (!OpcodeType.Instance.IsRegistered(type)) throw new InvalidOperationException($\"{type} has no opcode; regenerate protocol\");\nushort op = OpcodeType.Instance.GetOpcode(type);","typeGuard":"public bool IsRegistered(Type t) => typeOpcode.ContainsKey(t);","tryCatchPattern":"null","preventionTips":["Add message attributes when you add a message class.","Regenerate opcodes and load the right assemblies at init.","Unit-test that every sent type has a registered opcode."],"tags":["network","serialization","opcode","csharp"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}