RicoSuter/NSwag · error · InvalidOperationException
The command class is missing the CommandAttribute attribute.
Error message
The command class is missing the CommandAttribute attribute.
What it means
CommandLineProcessor.RegisterCommand(Type) requires the command type to be decorated with CommandAttribute, which supplies the command's CLI name. If GetCustomAttribute<CommandAttribute>() returns null it throws InvalidOperationException. The command cannot be registered without a name.
Solutions
- Add the CommandAttribute to the command class with the desired CLI name.
- Only register types you've verified carry CommandAttribute (filter before calling RegisterCommand).
- If registering many types via reflection, skip types without the attribute instead of throwing.
Example fix
// before
public class MyCommand : IConsoleCommand { ... }
processor.RegisterCommand(typeof(MyCommand));
// after
[Command("mycommand", "Does something")]
public class MyCommand : IConsoleCommand { ... }
processor.RegisterCommand(typeof(MyCommand)); Defensive patterns
Strategy: validation
Validate before calling
var candidates = assembly.GetTypes().Where(t => typeof(IConsoleCommand).IsAssignableFrom(t));
var bad = candidates.Where(t => t.GetCustomAttribute<CommandAttribute>() == null).ToList();
if (bad.Any()) Console.Error.WriteLine($"Missing CommandAttribute on: {string.Join(", ", bad.Select(t => t.Name))}"); Try / catch
try { processor.RegisterCommand(commandType); }
catch (InvalidOperationException ex) when (ex.Message.Contains("missing the CommandAttribute")) { Console.Error.WriteLine($"{commandType.Name} needs [Command(\"name\")]."); } Prevention
- Annotate every command class with [Command(...)] at creation time
- Filter reflection-based registration on types carrying CommandAttribute
- Add a test enumerating all commands to catch missing attributes early
When it happens
Trigger: Calling processor.RegisterCommand(typeof(MyCommand)) where MyCommand has no [Command("name", ...)] attribute; dynamically registering types from an assembly where some command-like classes were never annotated.
Common situations: Writing a custom NConsole command and forgetting the CommandAttribute; refactoring that removed the attribute; auto-registering all ICommand types in an assembly and one lacks the annotation.
Related errors
- The command '" + name + "' has already been added.
- The specified runtime in the document
- Project outputs could not be located in
- The ouput of is a 32-bit application and requires…
- The ouput of is a 64-bit application and requires…
AI-assisted analysis of RicoSuter/NSwag@63daf8fcc3 (2026-09-14).
Data as JSON: /api/errors/c5f2f1a4fa49642e.
Report an issue: GitHub.
Appendix: source
Thrown at src/NSwag.Commands/NConsole/CommandLineProcessor.cs:77
/// <summary>Loads all commands from an assembly (command classes must have the CommandAttribute with a defined Name).</summary>
/// <param name="assembly">The assembly.</param>
public void RegisterCommandsFromAssembly(Assembly assembly)
{
var commandTypes = assembly.ExportedTypes.ToDictionary(t => t, t => t.GetTypeInfo().GetCustomAttribute<CommandAttribute>());
foreach (var pair in commandTypes.Where(p => !string.IsNullOrEmpty(p.Value?.Name) && p.Key.GetTypeInfo().IsClass && !p.Key.GetTypeInfo().IsAbstract))
RegisterCommand(pair.Value.Name, pair.Key);
}
/// <summary>Adds a command.</summary>
/// <param name="commandType">Type of the command.</param>
/// <exception cref="InvalidOperationException">The command has already been added.</exception>
/// <exception cref="InvalidOperationException">The command class is missing the CommandAttribute attribute.</exception>
public void RegisterCommand(Type commandType)
{
var commandAttribute = commandType.GetTypeInfo().GetCustomAttribute<CommandAttribute>();
if (commandAttribute == null)
throw new InvalidOperationException("The command class is missing the CommandAttribute attribute.");
RegisterCommand(commandAttribute.Name, commandType);
}
/// <summary>Adds a command.</summary>
/// <param name="name">The name of the command.</param>
/// <param name="commandType">Type of the command.</param>
/// <exception cref="InvalidOperationException">The command has already been added.</exception>
public void RegisterCommand(string name, Type commandType)
{
if (_commands.ContainsKey(name))
throw new InvalidOperationException("The command '" + name + "' has already been added.");
_commands.Add(name.ToLowerInvariant(), commandType);
}
/// <summary>Processes the command in the given command line arguments.</summary>
/// <param name="args">The arguments.</param>View on GitHub (pinned to 63daf8fcc3)