winsw/winsw · error · ExtensionException
The loaded class is not a WinSW extension: {className}. Type
Error message
The loaded class is not a WinSW extension: {className}. Type is {type} What it means
After successfully instantiating the configured type, CreateExtensionInstance checks whether it implements IWinSWExtension. If not, it throws ExtensionException naming the class and its actual type. The type loaded fine; it simply isn't a valid WinSW extension.
Source
Thrown at src/WinSW.Core/Extensions/WinSWExtensionManager.cs:44
try
{
var t = Type.GetType(className);
if (t is null)
{
throw new ExtensionException(id, "Class " + className + " does not exist");
}
created = Activator.CreateInstance(t)!;
}
catch (Exception ex)
{
throw new ExtensionException(id, "Cannot load the class by name: " + className, ex);
}
if (!(created is IWinSWExtension extension))
{
throw new ExtensionException(id, "The loaded class is not a WinSW extension: " + className + ". Type is " + created.GetType());
}
return extension;
}
/// <summary>
/// Notifies all extensions that the wrapper is being started.
/// They are supposed to run the initialization logic.
/// If any extensions fails, WinSW startup should be interrupted.
/// </summary>
/// <exception cref="Exception">Start failure</exception>
public void FireOnWrapperStarted()
{
foreach (var ext in this.Extensions)
{
try
{
ext.Value.OnWrapperStarted();View on GitHub (pinned to 1d0ee4a91b)
Solutions
- Make the target class implement IWinSWExtension (and its members).
- Point className at the class that actually is the extension entry point.
- Rebuild against the current WinSW extension contract so the interface matches.
Example fix
// before
public class MyExt { /* no IWinSWExtension */ }
// after
public class MyExt : IWinSWExtension
{
public void Configure(IWinSWExtensionDescriptor descriptor, XmlElement config) { }
public void OnWrapperStarted() { }
public void BeforeWrapperStopped() { }
} Defensive patterns
Strategy: type-guard
Validate before calling
var t = Type.GetType(className);
if (t is null) throw new InvalidOperationException("Type unresolved");
if (!typeof(IWinSWExtension).IsAssignableFrom(t)) throw new InvalidOperationException($"{t} does not implement IWinSWExtension"); Type guard
static bool IsWinSWExtension(string className) => Type.GetType(className) is { } t && typeof(IWinSWExtension).IsAssignableFrom(t); Try / catch
try { manager.LoadExtension(id); }
catch (ExtensionException ex) when (ex.Message.Contains("not a WinSW extension")) { /* implement IWinSWExtension or fix className */ } Prevention
- Implement the full IWinSWExtension contract in your extension class.
- Point className at the real entry-point class.
- Type-guard before referencing in config.
When it happens
Trigger: className points to a class that exists and instantiates but does not implement IWinSWExtension — e.g. a utility class, a plain POCO, or a type implementing a different/older extension interface.
Common situations: Wrong class selected in config; extension author forgot to implement the interface; referencing an internal helper class; interface was renamed/moved across versions.
Related errors
- Class {className} does not exist
- Cannot load the class by name: {className}
- Extension has been already loaded
- <service> is missing in configuration XML
- <{tagName}> is missing in configuration XML
AI-assisted analysis of winsw/winsw@1d0ee4a91b (2026-08-13).
Data as JSON: /api/errors/6a40c23d9ac4c4be.
Report an issue: GitHub.