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

  1. Make the target class implement IWinSWExtension (and its members).
  2. Point className at the class that actually is the extension entry point.
  3. 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

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


AI-assisted analysis of winsw/winsw@1d0ee4a91b (2026-08-13). Data as JSON: /api/errors/6a40c23d9ac4c4be. Report an issue: GitHub.