{"record":{"id":"d5012aa6aaf54752","repo":"dotnet/yarp","slug":"expected-additional-args","errorCode":null,"errorMessage":"Expected additional args.","messagePattern":"Expected additional args\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"testassets/TestClient/CommandLineArgs.cs","lineNumber":57,"sourceCode":"                case \"--target\":\n                case \"-t\":\n                    result.Target = args[++i];\n                    break;\n            }\n        }\n\n        if (i < args.Length)\n        {\n            return ParseRemainder(result, args.AsSpan().Slice(i));\n        }\n\n        return result;\n\n        static CommandLineArgs ParseRemainder(CommandLineArgs result, Span<string> remainder)\n        {\n            if (remainder.Length == 0)\n            {\n                throw new ArgumentException(\"Expected additional args.\");\n            }\n\n            if (remainder.Length > 1)\n            {\n                throw new ArgumentException($\"Unexpected arg '{remainder[1]}'.\");\n            }\n\n            result.Scenario = remainder[0];\n            return result;\n        }\n    }\n\n    public static void ShowHelp()\n    {\n        Console.WriteLine(\"ReverseProxy SampleClient.\\n\");\n        Console.WriteLine(\"--scenario <name>, -s <name>: Runs only the specified scenario.\");\n        Console.WriteLine(\n            \"--target <uri>, -t <uri>: Sets the target uri. By default, 'https://localhost:1443/' is used.\");","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/testassets/TestClient/CommandLineArgs.cs#L39-L75","documentation":"Thrown by the SampleClient's CommandLineArgs.ParseRemainder when it is asked to parse a remainder that contains zero tokens. In the shipped parser this branch is effectively unreachable because ParseRemainder is only called when i < args.Length, so the slice always has length >= 1; it exists as a defensive guard for the 'a scenario name is required' intent.","triggerScenarios":"Conceptually: invoking the SampleClient in a way that reaches ParseRemainder with an empty remainder. In practice this requires an internal caller change; the normal CLI path cannot trigger it because the loop only delegates when there is at least one remaining token.","commonSituations":"Editing the parser and removing the guard that ensures remainder.Length > 0 before calling ParseRemainder; calling ParseRemainder directly from a test with an empty span.","solutions":["Pass a scenario name, e.g. `--scenario Http2PostExpectContinueScenario` or as a single positional argument.","If you modified CommandLineArgs, ensure ParseRemainder is only invoked with a non-empty remainder, or remove the now-dead branch."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Guard the CLI entry point: require a scenario before running.\nvar args2 = CommandLineArgs.Parse(args);\nif (string.IsNullOrEmpty(args2.Scenario)) {\n    CommandLineArgs.ShowHelp();\n    return 1;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always invoke the SampleClient with an explicit --scenario/-s value.","If you refactor the parser, keep the invariant that ParseRemainder only runs on a non-empty remainder.","Treat this branch as documentation of intent; cover it with a direct unit test if you depend on it."],"tags":["cli","args","test-client","defensive","yarp"],"backgroundTag":null,"analyzedSha":"bd11867bee7df522e7fd3effb08a9c85fd616908","analyzedAt":"2026-08-13T21:29:49.359Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}