{"record":{"id":"beb3c283100a4dd6","repo":"egametang/ET","slug":"long-hash-add-fail-type-fullname-samehashtype","errorCode":null,"errorMessage":"long hash add fail: {type.FullName} {sameHashType.FullName}","messagePattern":"long hash add fail: (.+?) (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"Packages/cn.etetet.lsentity/Scripts/Core/Share/LSEntitySystemSingleton.cs","lineNumber":46,"sourceCode":"                {\n                    oneTypeSystems.ClassType.Add(iSystemType.SystemType());\n                }\n            }\n            \n            foreach (var kv in CodeTypes.Instance.GetTypes())\n            {\n                Type type = kv.Value;\n                if (typeof(LSEntity).IsAssignableFrom(type))\n                {\n                    long hash = type.FullName.GetLongHashCode();\n                    try\n                    {\n                        this.lsEntityTypeLongHashCode.Add(type, type.FullName.GetLongHashCode());\n                    }\n                    catch (Exception e)\n                    {\n                        Type sameHashType = this.lsEntityTypeLongHashCode.GetKeyByValue(hash);\n                        throw new Exception($\"long hash add fail: {type.FullName} {sameHashType.FullName}\", e);\n                    }\n                }\n            }\n        }\n        \n        public long GetLongHashCode(Type type)\n        {\n            return this.lsEntityTypeLongHashCode.GetValueByKey(type);\n        }\n        \n        public TypeSystems.OneTypeSystems GetOneTypeSystems(Type type)\n        {\n            return this.TypeSystems.GetOneTypeSystems(type);\n        }\n        \n        public void LSRollback(Entity entity)\n        {\n            if (entity is not ILSRollback)","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.lsentity/Scripts/Core/Share/LSEntitySystemSingleton.cs#L28-L64","documentation":"Thrown by LSEntitySystemSingleton during initialization when two LSEntity subclass types produce the same GetLongHashCode() value from their FullName. The dictionary lsEntityTypeLongHashCode cannot hold two keys with the same value, so the Add fails. The inner ArgumentException is caught and re-thrown naming both colliding types. This is a hash collision on type full names.","triggerScenarios":"During framework initialization, the system scans all types assignable to LSEntity and computes a long hash from each type's FullName. If two different types have the same hash, the dictionary insert throws. This is extremely rare with a good hash but can happen with specific name combinations.","commonSituations":"Two LSEntity subclasses have very similar or identical full names in different namespaces. A hash collision occurs by chance (GetLongHashCode returns the same value for two distinct strings). Namespace/type renaming created a collision that wasn't there before.","solutions":["Rename one of the two colliding LSEntity types listed in the error to a different FullName to break the hash collision.","If renaming is not feasible, check the GetLongHashCode implementation for a weak hash function and improve it.","Ensure no two LSEntity subclasses share the same FullName across all loaded assemblies (check for duplicate class names in different namespaces that hash-collide)."],"exampleFix":"// before: two types collide on GetLongHashCode\nnamespace ET.Game.A { public class Unit : LSEntity { } }\nnamespace ET.Game.B { public class Hero : LSEntity { } } // collides\n// after: rename to break collision\nnamespace ET.Game.B { public class BattleHero : LSEntity { } }","handlingStrategy":"validation","validationCode":"// At build/editor time, verify no two LSEntity types have colliding LongHashCodes\nDictionary<long, Type> seen = new();\nforeach (var kv in CodeTypes.Instance.GetTypes())\n{\n    Type t = kv.Value;\n    if (typeof(LSEntity).IsAssignableFrom(t))\n    {\n        long hash = t.FullName.GetLongHashCode();\n        if (seen.TryGetValue(hash, out Type existing))\n            Debug.LogError($\"LSEntity hash collision: {t.FullName} vs {existing.FullName}\");\n        else\n            seen[hash] = t;\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run a hash collision check in the editor/build pipeline for all LSEntity types.","Avoid creating LSEntity subclasses with similar full names across namespaces.","If GetLongHashCode has a weak algorithm, improve it to reduce collision probability."],"tags":["lockstep","entity","hash-collision","initialization"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}