RicoSuter/NSwag · error · ArgumentException

does not implement property 'Prefix

Error message

{type.FullName} does not implement property 'Prefix'

What it means

RoutePrefixAttributeFacade wraps a route-prefix-like attribute and resolves its 'Prefix' property via type.GetRuntimeProperty("Prefix"). If the attribute's runtime type does not expose a public 'Prefix' property, the constructor throws ArgumentException naming the offending type. NSwag throws this when a custom RoutePrefixAttribute substitute does not implement the expected property.

Solutions

  1. Add a public 'Prefix' string property (with getter) to the custom attribute class.
  2. Use the framework's standard RoutePrefixAttribute instead of a custom implementation.
  3. Derive the custom attribute from the official RoutePrefixAttribute so 'Prefix' is inherited.
  4. Check the full type name in the message to identify which assembly supplies the non-conforming attribute.

Example fix

// before
public class ApiPrefixAttribute : Attribute { public string Value { get; } }

// after
public class ApiPrefixAttribute : Attribute { public string Prefix { get; } public ApiPrefixAttribute(string prefix) { Prefix = prefix; } }
Defensive patterns

Strategy: validation

Validate before calling

// Verify custom route-prefix attributes expose 'Prefix'
var ok = typeof(ApiPrefixAttribute).GetRuntimeProperty("Prefix") != null;
if (!ok) throw new InvalidOperationException("Custom RoutePrefix attribute must expose public 'Prefix' property");

Type guard

function hasPrefixProperty(attr) {
  return attr != null && typeof attr.Prefix === "string"; // C#: attr.GetType().GetRuntimeProperty("Prefix") != null
}

Try / catch

try { document = generator.Generate(settings); }
catch (ArgumentException ex) when (ex.Message.Contains("does not implement property 'Prefix'"))
{
    logger.LogError(ex, "Custom route prefix attribute lacks 'Prefix' property");
}

Prevention

When it happens

Trigger: Supplying a custom [RoutePrefix]-style attribute (or referencing a re-implementation of System.Web.Http.RoutePrefixAttribute in a different package) that lacks a public 'Prefix' property, when the WebApi document generator scans controller attributes and builds the facade.

Common situations: Porting code from ASP.NET (System.Web.Http) to ASP.NET Core or vice versa with a hand-rolled RoutePrefixAttribute that renamed the property; NuGet package swap changing the attribute implementation; typos like 'Prefixe' or a private setter with no public getter being fine but a renamed property not.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of RicoSuter/NSwag@63daf8fcc3 (2026-09-14). Data as JSON: /api/errors/624e5cba2142c087. Report an issue: GitHub.

Appendix: source

Thrown at src/NSwag.Generation.WebApi/Infrastructure/RoutePrefixAttributeFacade.cs:29

namespace NSwag.Generation.WebApi.Infrastructure
{
    /// <summary>
    /// Uses reflection to provide a common interface to the following types:
    /// * RoutePrefixAttribute
    /// * IRoutePrefix
    /// </summary>
    internal sealed class RoutePrefixAttributeFacade
    {
        private readonly PropertyInfo _prefix;

        public RoutePrefixAttributeFacade(Attribute attr)
        {
            var type = attr.GetType();

            _prefix = type.GetRuntimeProperty("Prefix");
            if (_prefix == null)
            {
                throw new ArgumentException($"{type.FullName} does not implement property 'Prefix'");
            }

            Attribute = attr;
        }

        public Attribute Attribute { get; }

        public string Prefix => (string)_prefix.GetValue(Attribute);

        public static RoutePrefixAttributeFacade TryMake(Attribute a)
        {
            var type = a.GetType();

            if (type.Name == "RoutePrefixAttribute" ||
                type.GetTypeInfo().ImplementedInterfaces.Any(i => i.Name == "IRoutePrefix"))
            {
                return new RoutePrefixAttributeFacade(a);
            }

View on GitHub (pinned to 63daf8fcc3)