icsharpcode/ILSpy · error · NotSupportedException

HandleKind {handle.Kind} is not supported!

Error message

HandleKind {handle.Kind} is not supported!

What it means

NotSupportedException from DecompileExtension's default case: only TypeDefinition, MethodDefinition and PropertyDefinition handles are decompilable as extension members. Any other HandleKind (field, event, etc.) is rejected. C# extension members are methods only; properties appear for VB; fields and events are not valid extension members.

Source

Thrown at ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs:1506

					var accessor = propDef.Getter ?? propDef.Setter;
					memberInfo = extensionInfo.InfoOfExtensionMember((IMethod)accessor!.MemberDefinition).GetValueOrDefault();
					subst = new TypeParameterSubstitution(memberInfo.ExtensionGroupingTypeParameters, null);
					propDef = (IProperty)propDef.Specialize(subst);
					EntityDeclaration prop = DoDecompile(propDef, decompileRun, new SimpleTypeResolveContext(propDef), extensionInfo);
					syntaxTree.Members.Add(prop);
					RemoveAttribute(prop, KnownAttribute.ExtensionMarker);
					if (propDef.Getter != null)
					{
						RemoveAttribute(prop.GetChild(Slots.Getter)!, KnownAttribute.ExtensionMarker);
					}
					if (propDef.Setter != null)
					{
						RemoveAttribute(prop.GetChild(Slots.Setter)!, KnownAttribute.ExtensionMarker);
					}
					RunTransforms(syntaxTree, decompileRun, new SimpleTypeResolveContext(propDef.DeclaringTypeDefinition));
					break;
				default:
					throw new NotSupportedException($"HandleKind {handle.Kind} is not supported!");
			}
			return syntaxTree;
		}

		ITypeDefinition? FindCommonDeclaringTypeDefinition(ITypeDefinition? a, ITypeDefinition? b)
		{
			if (a == null || b == null)
				return null;
			var declaringTypes = a.GetDeclaringTypeDefinitions();
			var set = new HashSet<ITypeDefinition>(b.GetDeclaringTypeDefinitions());
			return declaringTypes.FirstOrDefault(set.Contains);
		}

		/// <summary>
		/// Decompile the specified types and/or members.
		/// </summary>
		public string DecompileAsString(params EntityHandle[] definitions)
		{

View on GitHub (pinned to 60c08fcb74)

Solutions

  1. Gate the call on handle.Kind being TypeDefinition, MethodDefinition or PropertyDefinition before invoking DecompileExtension.
  2. Filter extension-group members to the decompilable kinds (properties and methods).

Example fix

// before
var tree = decompiler.DecompileExtension(handle);

// after
if (handle.Kind is not (HandleKind.TypeDefinition or HandleKind.MethodDefinition or HandleKind.PropertyDefinition))
    throw new NotSupportedException($"DecompileExtension only takes type/method/property handles, got {handle.Kind}");
var tree = decompiler.DecompileExtension(handle);
Defensive patterns

Strategy: type-guard

Validate before calling

if (handle.Kind is not (HandleKind.TypeDefinition or HandleKind.MethodDefinition or HandleKind.PropertyDefinition))
    throw new NotSupportedException($"DecompileExtension only takes type/method/property handles, got {handle.Kind}");
var tree = decompiler.DecompileExtension(handle);

Type guard

static bool IsDecompilableExtensionMember(EntityHandle h) =>
    h.Kind is HandleKind.TypeDefinition or HandleKind.MethodDefinition or HandleKind.PropertyDefinition;

Prevention

When it happens

Trigger: Passing a FieldDefinitionHandle or EventDefinitionHandle (or any non-type/method/property handle) to DecompileExtension.

Common situations: Treating all members of an extension group uniformly; a handle selected by metadata-token comparison that happens to be a field/event.

Related errors


AI-assisted analysis of icsharpcode/ILSpy@60c08fcb74 (2026-08-13). Data as JSON: /api/errors/55af2fa554c95efb. Report an issue: GitHub.