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

  1. Compare the listed unused arguments against valid options for the command and fix typos (e.g. /input not /intput).
  2. Check `nswag help <command>` (or the command's documentation) for the exact supported argument names in your NSwag version.
  3. Quote paths containing spaces so one option doesn't split into stray tokens.
  4. 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

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


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)