{"record":{"id":"b13cf338e70eb513","repo":"chocolatey/choco","slug":"a-packages-config-file-is-only-used-with-installs","errorCode":null,"errorMessage":"A packages.config file is only used with installs.","messagePattern":"A packages\\.config file is only used with installs\\.","errorType":"exception","errorClass":"ApplicationException","httpStatus":null,"severity":"error","filePath":"src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs","lineNumber":1145,"sourceCode":"        {\r\n            ValidatePackageNames(config);\r\n\r\n            this.Log().Info(@\"Upgrading the following packages:\");\r\n            this.Log().Info(ChocolateyLoggers.Important, @\"{0}\".FormatWith(config.PackageNames));\r\n\r\n            if (string.IsNullOrWhiteSpace(config.Sources))\r\n            {\r\n                this.Log().Error(ChocolateyLoggers.Important, @\"Upgrading was NOT successful. There are no sources enabled for\r\n packages and none were passed as arguments.\");\r\n                Environment.ExitCode = 1;\r\n                return new ConcurrentDictionary<string, PackageResult>();\r\n            }\r\n\r\n            this.Log().Info(@\"By upgrading, you accept licenses for the packages.\");\r\n\r\n            foreach (var packageConfigFile in config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries).OrEmpty().Where(p => p.EndsWith(\".config\")).ToList())\r\n            {\r\n                throw new ApplicationException(\"A packages.config file is only used with installs.\");\r\n            }\r\n\r\n            var packageUpgrades = new ConcurrentDictionary<string, PackageResult>();\r\n\r\n            try\r\n            {\r\n                GetInitialEnvironment(config, allowLogging: true);\r\n\r\n                ConcurrentDictionary<string, PackageResult> results;\r\n\r\n                if (config.SourceType.IsEqualTo(SourceTypes.Normal))\r\n                {\r\n                    var action = new Action<PackageResult, ChocolateyConfiguration>((packageResult, configuration) => HandlePackageResult(packageResult, configuration, CommandNameType.Upgrade));\r\n                    var beforeUpgradeAction = new Action<PackageResult, ChocolateyConfiguration>((packageResult, configuration) => BeforeModifyAction(packageResult, configuration));\r\n\r\n                    results = _nugetService.Upgrade(config, action, beforeUpgradeAction);\r\n                }\r\n                else\r","sourceCodeStart":1127,"sourceCodeEnd":1163,"githubUrl":"https://github.com/chocolatey/choco/blob/0d5abdd10cc177a141e69547cad6935b419b6c17/src/chocolatey/infrastructure.app/services/ChocolateyPackageService.cs#L1127-L1163","documentation":"Thrown as an ApplicationException during UpgradeClean/Upgrade when any package name in config.PackageNames ends with '.config'. A packages.config file is a manifest listing multiple packages to install and is only valid for the install command — passing it to upgrade is an explicit error, not a supported workflow.","triggerScenarios":"Calling the Upgrade method (e.g., 'choco upgrade packages.config') where config.PackageNames contains a token ending in '.config'. The code splits PackageNames by the separator and throws immediately if any element matches the .config extension.","commonSituations":"A user attempts 'choco upgrade packages.config' thinking it will upgrade all packages listed in the config file. This is unsupported — packages.config is only recognized by 'choco install'. Also triggered when a package is literally named with a .config suffix.","solutions":["Use 'choco install packages.config -y' instead of upgrade to install from a packages.config file.","To upgrade packages listed in a packages.config, first install them, then use 'choco upgrade all' or list individual package names.","Extract package names from the .config file and pass them individually: 'choco upgrade pkg1 pkg2 pkg3 -y'."],"exampleFix":"// before: passing .config file to upgrade\nchoco upgrade packages.config -y\n\n// after: use install for packages.config, upgrade for individual packages\nchoco install packages.config -y\nchoco upgrade pkg1 pkg2 pkg3 -y","handlingStrategy":"validation","validationCode":"// Before calling Upgrade, validate no package name ends with .config\nvar packageNames = config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries);\nif (packageNames.Any(p => p.EndsWith(\".config\", StringComparison.OrdinalIgnoreCase)))\n{\n    throw new InvalidOperationException(\"packages.config files cannot be used with upgrade. Use install instead.\");\n}","typeGuard":"public static bool IsValidUpgradePackageName(string packageName)\n{\n    return !packageName.EndsWith(\".config\", StringComparison.OrdinalIgnoreCase);\n}","tryCatchPattern":"try\n{\n    _packageService.Upgrade(config);\n}\ncatch (ApplicationException ex) when (ex.Message.Contains(\"packages.config file is only used with installs\"))\n{\n    logger.Error(\"Cannot upgrade from packages.config. Use 'choco install packages.config' first, then upgrade individual packages.\");\n}","preventionTips":["Never pass .config files to 'choco upgrade' — use 'choco install' for packages.config.","Validate command-line arguments before passing them to the API.","Parse packages.config files externally and pass individual names to upgrade."],"tags":["packages-config","upgrade","validation","chocolatey"],"backgroundTag":null,"analyzedSha":"0d5abdd10cc177a141e69547cad6935b419b6c17","analyzedAt":"2026-08-13T18:33:03.301Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}