{"record":{"id":"083cb4628acfa83a","repo":"louthy/language-ext","slug":"invalidoperationexception-resolver","errorCode":null,"errorMessage":"InvalidOperationException","messagePattern":"InvalidOperationException","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"LanguageExt.Core/Traits/Resolve/Resolver.cs","lineNumber":114,"sourceCode":"        return null;\n    }\n\n    public static MethodInfo GetHashCodeMethodAlways(Type type)\n    {\n        Type[] traits = [typeof(HashableResolve<>), typeof(EqResolve<>), typeof(OrdResolve<>)];\n        foreach (var trait in traits)\n        {\n            var impl   = trait.MakeGenericType(type);\n            var exists = (bool?)impl.GetProperty(\"Exists\")?.GetValue(null) ?? false;\n            if (exists)\n            {\n                var method = impl.GetMethod(\"GetHashCode\", BindingFlags.Static | BindingFlags.Public, [type]);\n                if (method is not null) return method;\n            }\n        }\n        \n        var impl2   = typeof(HashableResolve<>).MakeGenericType(type);\n        return impl2.GetMethod(\"GetHashCode\", BindingFlags.Static | BindingFlags.Public, [type]) ?? throw new InvalidOperationException();\n    }\n\n    public static MethodInfo? GetEqualsMethod(Type type)\n    {\n        Type[] traits = [typeof(EqResolve<>), typeof(OrdResolve<>)];\n        foreach (var trait in traits)\n        {\n            var impl   = trait.MakeGenericType(type);\n            var exists = (bool?)impl.GetProperty(\"Exists\")?.GetValue(null) ?? false;\n            if (exists)\n            {\n                var method = impl.GetMethod(\"Equals\", BindingFlags.Static | BindingFlags.Public, [type, type]);\n                if (method is not null) return method;\n            }\n        }\n        return null;\n    }\n","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/louthy/language-ext/blob/2f0e3628242889774d4141960a35671a0280051f/LanguageExt.Core/Traits/Resolve/Resolver.cs#L96-L132","documentation":"Resolver.GetHashCodeMethodAlways searches HashableResolve/EqResolve/OrdResolve for a usable GetHashCode MethodInfo and, when none of the resolvers report Exists, falls back to HashableResolve<T>.GetMethod(\"GetHashCode\") and throws InvalidOperationException if that is also absent. It means the requested type has no Hashable/Eq/Ord instance registered, so a hash-code method is guaranteed unavailable.","triggerScenarios":"Calling APIs that require hashing (dictionaries, hash sets, Hashablerelude helpers) for a type T where HashableResolve<T>, EqResolve<T> and OrdResolve<T>.Exists are all false — i.e. no static Hashable<T>/Eq<T>/Ord<T> instance exists for T and no 'Hashable<T>'-named convention class was found.","commonSituations":"Forgetting to write a Hashable<T>/Eq<T> instance for a custom struct/class before using it as a key; type-named convention classes misspelled (resolver searches for 'HashableT'-style names via Resolver.Find); instances defined in an assembly that failed to load.","solutions":["Implement a Hashable<T> instance (or Eq<T>/Ord<T>) for the type in the same or a referenced assembly.","Name the conventional resolver class correctly so Resolver.Find can locate it (prefix 'Hashable' + type name).","Verify the assembly containing the instance is referenced and loadable.","Check the nullable Resolver.GetHashCodeMethod first if your code can fall back to BCL GetHashCode instead."],"exampleFix":"// before\nvar set = HashSet.create<Money>(...); // InvalidOperationException: no hashable instance\n// after\npublic class MoneyHashable : Hashable<Money>\n{\n    public override int GetHashCode(Money x) => x.Amount.GetHashCode() ^ x.Currency.GetHashCode();\n    public override bool Equals(Money x, Money y) => x.Amount == y.Amount && x.Currency == y.Currency;\n}","handlingStrategy":"fallback","validationCode":"// pre-check before hashing API that uses 'Always' resolution\nif (!HashableResolve<Money>.Exists && !EqResolve<Money>.Exists && !OrdResolve<Money>.Exists)\n    throw new InvalidOperationException($\"No Hashable/Eq/Ord instance for Money\");","typeGuard":"static bool HasHashableInstance<T>() => HashableResolve<T>.Exists || EqResolve<T>.Exists || OrdResolve<T>.Exists;","tryCatchPattern":"MethodInfo hashMethod;\ntry { hashMethod = Resolver.GetHashCodeMethodAlways(typeof(T)); }\ncatch (InvalidOperationException)\n{\n    hashMethod = null; // fall back to EqualityComparer<T>.Default.GetHashCode\n}","preventionTips":["Write a Hashable<T> instance for every type used as a key or in a set","Follow the trait-instance naming convention exactly so Resolver.Find can locate it","Ensure assemblies containing instances are referenced and loadable","Prefer the nullable Resolver.GetHashCodeMethod when a fallback is acceptable"],"tags":["type-class-resolution","gethashcode","reflection","languageext"],"backgroundTag":"method-not-implemented","analyzedSha":"2f0e3628242889774d4141960a35671a0280051f","analyzedAt":"2026-09-15T03:31:55.716Z","contentChangedAt":"2026-09-15T03:31:55.716Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}