{"record":{"id":"6112e93c769eb8e4","repo":"icsharpcode/ILSpy","slug":"cannot-use-an-uncached-type-system-in-the-decompil","errorCode":null,"errorMessage":"Cannot use an uncached type system in the decompiler.","messagePattern":"Cannot use an uncached type system in the decompiler\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs","lineNumber":380,"sourceCode":"\t\t/// <summary>\r\n\t\t/// Creates a new <see cref=\"CSharpDecompiler\"/> instance from the given <paramref name=\"module\"/> using the given <paramref name=\"assemblyResolver\"/> and <paramref name=\"settings\"/>.\r\n\t\t/// </summary>\r\n\t\tpublic CSharpDecompiler(MetadataFile module, IAssemblyResolver assemblyResolver, DecompilerSettings settings)\r\n\t\t\t: this(new DecompilerTypeSystem(module, assemblyResolver, settings), settings)\r\n\t\t{\r\n\t\t}\r\n\r\n\t\t/// <summary>\r\n\t\t/// Creates a new <see cref=\"CSharpDecompiler\"/> instance from the given <paramref name=\"typeSystem\"/> and the given <paramref name=\"settings\"/>.\r\n\t\t/// </summary>\r\n\t\tpublic CSharpDecompiler(IDecompilerTypeSystem typeSystem, DecompilerSettings settings)\r\n\t\t{\r\n\t\t\tthis.typeSystem = typeSystem ?? throw new ArgumentNullException(nameof(typeSystem));\r\n\t\t\tthis.settings = settings;\r\n\t\t\tthis.module = typeSystem.MainModule;\r\n\t\t\tthis.metadata = module.MetadataFile.Metadata;\r\n\t\t\tif (module.TypeSystemOptions.HasFlag(TypeSystemOptions.Uncached))\r\n\t\t\t\tthrow new ArgumentException(\"Cannot use an uncached type system in the decompiler.\");\r\n\t\t}\r\n\r\n\t\t#region MemberIsHidden\r\n\t\t/// <summary>\r\n\t\t/// Determines whether a <paramref name=\"member\"/> should be hidden from the decompiled code. This is used to exclude compiler-generated code that is handled by transforms from the output.\r\n\t\t/// </summary>\r\n\t\t/// <param name=\"module\">The module containing the member.</param>\r\n\t\t/// <param name=\"member\">The metadata token/handle of the member. Can be a TypeDef, MethodDef or FieldDef.</param>\r\n\t\t/// <param name=\"settings\">The settings used to determine whether code should be hidden. E.g. if async methods are not transformed, async state machines are included in the decompiled code.</param>\r\n\t\tpublic static bool MemberIsHidden(MetadataFile? module, EntityHandle member, DecompilerSettings settings)\r\n\t\t{\r\n\t\t\tif (module == null || member.IsNil)\r\n\t\t\t\treturn false;\r\n\t\t\tvar metadata = module.Metadata;\r\n\t\t\tstring name;\r\n\t\t\tswitch (member.Kind)\r\n\t\t\t{\r\n\t\t\t\tcase HandleKind.MethodDefinition:\r","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/icsharpcode/ILSpy/blob/60c08fcb74fcc183130f73c861ed35cf944d0bf1/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs#L362-L398","documentation":"Thrown by the CSharpDecompiler constructor when module.TypeSystemOptions has the Uncached flag. The decompiler makes many repeated metadata lookups and requires a cached type system; an uncached one would be correct but unusably slow and is rejected with ArgumentException.","triggerScenarios":"Passing an IDecompilerTypeSystem built from a MetadataFile loaded with TypeSystemOptions.Uncached (e.g. via UniversalAssemblyReader / an uncached assembly), or constructing the DecompilerTypeSystem on top of a metadata file opened with the uncached option.","commonSituations":"Caller reused an uncached reader for performance in another tool and passed the same module to the decompiler; loading assemblies with the streaming/uncached option then decompiling.","solutions":["Do not set TypeSystemOptions.Uncached for modules you intend to decompile.","Build the type system from a cached MetadataFile (default load path).","Use the CSharpDecompiler(MetadataFile, IAssemblyResolver, DecompilerSettings) overload which constructs a cached DecompilerTypeSystem internally."],"exampleFix":"// before: module loaded uncached\nvar ts = new DecompilerTypeSystem(uncachedModule, resolver, settings);\nvar decompiler = new CSharpDecompiler(ts, settings); // ArgumentException\n\n// after: load the module cached (default)\nvar module = new PEFile(path); // cached metadata by default\nvar decompiler = new CSharpDecompiler(module, resolver, settings);","handlingStrategy":"validation","validationCode":"if (typeSystem.MainModule.TypeSystemOptions.HasFlag(TypeSystemOptions.Uncached))\n    throw new ArgumentException(\"Use a cached type system for decompilation.\");\nvar decompiler = new CSharpDecompiler(typeSystem, settings);","typeGuard":null,"tryCatchPattern":"try {\n    var decompiler = new CSharpDecompiler(typeSystem, settings);\n} catch (ArgumentException ex) when (ex.Message.Contains(\"uncached\")) {\n    // rebuild the type system from a cached module and retry\n}","preventionTips":["Keep decompilation and streaming/uncached metadata loading on separate module instances.","Default to cached PEFile/MetadataFile for anything handed to the decompiler."],"tags":["decompiler","csharp","configuration"],"backgroundTag":null,"analyzedSha":"60c08fcb74fcc183130f73c861ed35cf944d0bf1","analyzedAt":"2026-08-13T11:34:51.223Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}