RicoSuter/NSwag · error · UnusedArgumentException
Used arguments ( ) != Provided arguments ( ) -> Check [ ]
Error message
Used arguments ({usedArgs.Count}) != Provided arguments ({commandArguments.Count()}) -> Check [{string.Join(", ", unusedArgs)}] What it means
After a command runs, ProcessSingleAsync verifies every argument token parsed from the command line was actually consumed by some command property. If usedArgs.Count != provided count, unused tokens (possibly looking like values rather than flags) are listed and it throws UnusedArgumentException. Usually a misspelled or unrecognized option slipped through the parser.
Solutions
- Compare the listed unused arguments against valid options for the command and fix typos (e.g. /input not /intput).
- Check `nswag help <command>` (or the command's documentation) for the exact supported argument names in your NSwag version.
- Quote paths containing spaces so one option doesn't split into stray tokens.
- Remove options deprecated/renamed in your NSwag version.
Example fix
// before nswag openapi2csclient /intput:swagger.json /output:Client.cs // after nswag openapi2csclient /input:swagger.json /output:Client.cs
Defensive patterns
Strategy: validation
Validate before calling
var validOptions = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "input", "output", "namespace", ... };
var unknown = rawArgs.Where(a => a.StartsWith("/") && !validOptions.Contains(a.TrimStart('/').Split(':')[0])).ToList();
if (unknown.Any()) throw new ArgumentException($"Unrecognized options: {string.Join(", ", unknown)}"); Try / catch
try { result = await processor.ProcessSingleAsync(args, typeof(cmd)); }
catch (UnusedArgumentException ex) { Console.Error.WriteLine($"Check option names — {ex.Message}"); } Prevention
- Verify option names with `nswag help <command>` for your NSwag version
- Watch for typos like /intput vs /input — the parser reports them only after the command runs
- Quote arguments containing spaces so they don't split into stray tokens
- When upgrading NSwag, diff renamed/removed options before reusing old command lines
When it happens
Trigger: Passing an argument that matches no [Argument] property — e.g. a typo like /intput:swagger.json, an option removed in a newer NSwag version, or a stray token (extra file path, unquoted space splitting an argument) — so it remains in unusedArgs after processing.
Common situations: Typo'd option names; upgrading NSwag where an option was renamed; copy-pasting options from an .nswag file onto the command line where they aren't valid; spaces inside paths breaking one argument into two.
Understand the failure class
Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.
Related errors
- 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…
- No project (.csproj) file could be found under directory
AI-assisted analysis of RicoSuter/NSwag@63daf8fcc3 (2026-09-14).
Data as JSON: /api/errors/4d9e15bc20d8fa65.
Report an issue: GitHub.
Appendix: source
Thrown at src/NSwag.Commands/NConsole/CommandLineProcessor.cs:181
if (value != null)
property.SetValue(command, value);
if (usedArg != null)
usedArgs.Add(usedArg);
}
}
if (usedArgs.Count != commandArguments.Count())
{
var unusedArgs = new List<string>();
foreach (string arg in commandArguments)
{
if (!usedArgs.Contains(arg))
{
unusedArgs.Add(arg);
}
}
throw new UnusedArgumentException($"Used arguments ({usedArgs.Count}) != Provided arguments ({commandArguments.Count()}) -> Check [{string.Join(", ", unusedArgs)}]");
}
var output = await command.RunAsync(this, _consoleHost);
return new CommandResult
{
Command = command,
Output = output
};
}
else
throw new InvalidOperationException("The command '" + commandName + "' could not be found.");
}
/// <summary>Processes the command in the given command line arguments.</summary>
/// <param name="args">The arguments.</param>
/// <param name="input">The output from the previous command.</param>
/// <returns>The exeucuted command.</returns>
/// <exception cref="InvalidOperationException">The command could not be found.</exception>View on GitHub (pinned to 63daf8fcc3)