#4092·ILSpy

nugetfuzz: stage the forward targets of facade assemblies

Author: siegfriedpammerCreated Aug 31, 2026Updated Aug 31, 2026

During a full nuget.org catalog sweep with TestTools/nugetfuzz.cs, the largest group of decompiler warnings in packages whose references all resolved turned out to be a staging gap in the tool itself, not a decompiler problem.

Symptom. netstandard2.0 / netcoreapp packages (storyteller, nancy, csla-core, fluentnhibernate, nhibernate, specflow, neo4jclient, ...) produce Unknown result type / Expected O, but got Unknown warnings even though the run reports every reference resolved.

Witness. storyteller 5.4.0, StoryTeller.Util.XmlExtensions:

IL_0001: call bool [netstandard]System.IO.File::Exists(string)      // resolves fine
IL_0008: newobj instance void [netstandard]System.Xml.XmlDocument::.ctor()  // goes Unknown

Root cause. TypeRefs in netstandard-targeted assemblies are scoped to the netstandard facade, which only contains ExportedType forwards. Forwards whose target assembly happens to be in the staged closure resolve; forwards to assemblies outside it (System.Xml.* -> System.Xml.ReaderWriter, System.Dynamic.* -> System.Linq.Expressions) dead-end, the type becomes UnknownType, and ILReader warns at every use. The per-assembly "refs resolved" counter stays green because the facade itself resolved.

Proof it is not the decompiler. Standalone ilspycmd (which probes the installed runtime, where the forward targets exist) decompiles the same types from the same DLLs with zero warnings, so the forwarder-following logic is fine.

Suggestion. When staging an assembly closure, additionally stage the assemblies referenced by the ExportedType table of any facade included in the closure (transitively). This removes the largest warning group from sweep results and makes the WARNING channel meaningful for fully-resolved packages.


Filed by an AI agent (Claude, claude-fable-5, Claude Code) on behalf of @siegfriedpammer; findings verified against ILSpy master on 2026-08-31.