{"record":{"id":"8ab37cf5ea4df1e9","repo":"chocolatey/choco","slug":"a-single-apikey-command-must-be-listed-please-see","errorCode":null,"errorMessage":"A single apikey command must be listed. Please see the help menu for those commands.","messagePattern":"A single apikey command must be listed\\. Please see the help menu for those commands\\.","errorType":"exception","errorClass":"ApplicationException","httpStatus":null,"severity":"error","filePath":"src/chocolatey/infrastructure.app/commands/ChocolateyApiKeyCommand.cs","lineNumber":62,"sourceCode":"            configuration.Sources = null;\r\n\r\n            optionSet\r\n                .Add(\"s=|source=\",\r\n                     \"Source [REQUIRED] - The source location for the key\",\r\n                     option => configuration.Sources = option.UnquoteSafe())\r\n                .Add(\"k=|key=|apikey=|api-key=\",\r\n                     \"ApiKey - The API key for the source. This is the authentication that identifies you and allows you to push to a source. With some sources this is either a key or it could be a user name and password specified as 'user:password'.\",\r\n                     option => configuration.ApiKeyCommand.Key = option.UnquoteSafe())\r\n                ;\r\n        }\r\n\r\n        public virtual void ParseAdditionalArguments(IList<string> unparsedArguments, ChocolateyConfiguration configuration)\r\n        {\r\n            configuration.Input = string.Join(\" \", unparsedArguments);\r\n\r\n            if (unparsedArguments.Count > 1)\r\n            {\r\n                throw new ApplicationException(\"A single apikey command must be listed. Please see the help menu for those commands.\");\r\n            }\r\n\r\n            var command = ApiKeyCommandType.Unknown;\r\n            var unparsedCommand = unparsedArguments.DefaultIfEmpty(string.Empty).FirstOrDefault();\r\n\r\n            if (!Enum.TryParse(unparsedCommand, true, out command) || command == ApiKeyCommandType.Unknown)\r\n            {\r\n                command = ApiKeyCommandType.List;\r\n\r\n                if (!string.IsNullOrWhiteSpace(unparsedCommand))\r\n                {\r\n                    this.Log().Warn(\"Unknown command {0}. Setting to list.\".FormatWith(unparsedCommand));\r\n                }\r\n                else if (!string.IsNullOrWhiteSpace(configuration.ApiKeyCommand.Key))\r\n                {\r\n                    this.Log().Warn(\"API key provided. Setting command to add.\");\r\n                    command = ApiKeyCommandType.Add;\r\n                }\r","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/chocolatey/choco/blob/0d5abdd10cc177a141e69547cad6935b419b6c17/src/chocolatey/infrastructure.app/commands/ChocolateyApiKeyCommand.cs#L44-L80","documentation":"The apikey command accepts at most one positional subcommand token (list/add/remove). ParseAdditionalArguments throws when unparsedArguments.Count > 1, because more than one leftover positional argument means the user supplied multiple subcommand-like tokens. It directs the user to the help menu to see the valid single commands.","triggerScenarios":"Running 'choco apikey add remove', 'choco apikey list extra', or any invocation where more than one unflagged positional token remains after option parsing.","commonSituations":"Copying examples that concatenate subcommands; scripting that appends a source as a positional argument instead of -s; misunderstanding that apikey takes exactly one verb.","solutions":["Pass a single apikey subcommand (list, add, or remove) and use flags for source/key.","Use the explicit form: 'choco apikey add -s <source> -k <key>'.","Run 'choco apikey -?' to confirm accepted subcommands."],"exampleFix":"# before\nchoco apikey add remove -s https://feed -k abc\n\n# after\nchoco apikey add -s https://feed -k abc","handlingStrategy":"validation","validationCode":"// Build apikey args with at most one positional subcommand.\nvar verbs = new[] { \"list\", \"add\", \"remove\" };\nvar positional = tokens.Where(t => !t.StartsWith(\"-\")).ToList();\nif (positional.Count(t => verbs.Contains(t, StringComparer.OrdinalIgnoreCase)) > 1)\n{\n    throw new ArgumentException(\"apikey accepts a single subcommand.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use the explicit 'choco apikey <verb> -s ... -k ...' form with flags.","Count positional tokens before invoking choco in scripts.","Consult 'choco apikey -?' when unsure of accepted subcommands."],"tags":["apikey","arguments","cli","validation"],"backgroundTag":null,"analyzedSha":"0d5abdd10cc177a141e69547cad6935b419b6c17","analyzedAt":"2026-08-13T18:33:03.301Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}