{"record":{"id":"34f399cb5ef3df33","repo":"microsoft/aspire","slug":"the-project-file-was-updated-successfully-but-the","errorCode":null,"errorMessage":"The project file was updated successfully, but the PackageVersion entry for '{packageId}' could not be removed from '{cpmInfo.DirectoryPackagesPropsFile.FullName}': {ex.Message}. Please manually remove the <PackageVersion Include=\"{packageId}\" ... /> entry from this file to avoid NU1009 build errors.","messagePattern":"The project file was updated successfully, but the PackageVersion entry for '(.+?)' could not be removed from '(.+?)': (.+?)\\. Please manually remove the <PackageVersion Include=\"(.+?)\" \\.\\.\\. /> entry from this file to avoid NU1009 build errors\\.","errorType":"exception","errorClass":"ProjectUpdaterException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/Projects/ProjectUpdater.cs","lineNumber":859,"sourceCode":"                return;\n            }\n\n            var parentNode = packageVersionNode.ParentNode;\n\n            RemoveNodeWithWhitespace(packageVersionNode);\n\n            if (parentNode.Name == \"ItemGroup\" && IsEmptyOrWhitespace(parentNode))\n            {\n                RemoveNodeWithWhitespace(parentNode);\n            }\n\n            propsDocument.Save(cpmInfo.DirectoryPackagesPropsFile.FullName);\n        }\n        catch (Exception ex)\n        {\n            // The csproj has already been updated at this point, so we can't roll back.\n            // Inform the user what manual step is needed to complete the migration.\n            throw new ProjectUpdaterException(\n                string.Format(\n                    CultureInfo.InvariantCulture,\n                    \"The project file was updated successfully, but the PackageVersion entry for '{0}' could not be \" +\n                    \"removed from '{1}': {2}. Please manually remove the <PackageVersion Include=\\\"{0}\\\" ... /> \" +\n                    \"entry from this file to avoid NU1009 build errors.\",\n                    packageId,\n                    cpmInfo.DirectoryPackagesPropsFile.FullName,\n                    ex.Message),\n                ex);\n        }\n    }\n\n    private static async Task UpdateSdkVersionInSingleFileAppHostAsync(FileInfo projectFile, NuGetPackageCli package)\n    {\n        var fileContent = await File.ReadAllTextAsync(projectFile.FullName);\n\n        // Look for the #:sdk Aspire.AppHost.Sdk@<version> directive\n        var match = SdkDirectiveRegex().Match(fileContent);","sourceCodeStart":841,"sourceCodeEnd":877,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/Projects/ProjectUpdater.cs#L841-L877","documentation":"During CPM (Central Package Management) migration, the updater first updates the csproj to use Aspire.* package versions, then removes the corresponding <PackageVersion> entries from Directory.Packages.props. If that removal throws (file locked, save failure, parse error), the csproj is already modified and cannot be rolled back, so this exception tells the user the exact manual step left to avoid NU1009 (transitive Central Package Management) errors.","triggerScenarios":"ProjectUpdater removing a PackageVersion entry from Directory.Packages.props after already saving the updated csproj, and the props-file write/parse fails — e.g. Directory.Packages.props is read-only, locked by another process, or malformed XML.","commonSituations":"Directory.Packages.props open in an editor or held by a build; insufficient write permissions on the props file; Directory.Packages.props with XML that fails to parse mid-migration.","solutions":["Manually remove the <PackageVersion Include=\"{packageId}\" ... /> entry for the named package from Directory.Packages.props, then build to confirm no NU1009 error.","Close editors/lockers or fix file permissions on Directory.Packages.props and re-run `aspire update`.","If the file is malformed XML, repair or restore it before hand-editing the PackageVersion entry."],"exampleFix":"// before (Directory.Packages.props)\n<PackageVersion Include=\"Aspire.Hosting.AppHost\" Version=\"9.0.0\" />\n// after\n<!-- entry removed -->","handlingStrategy":"try-catch","validationCode":"var propsPath = Path.Combine(repoRoot, \"Directory.Packages.props\");\nif (File.Exists(propsPath))\n{\n    using var stream = File.Open(propsPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None); // throws if locked/read-only\n    var doc = new XmlDocument(); doc.Load(stream); // throws if malformed\n}","typeGuard":null,"tryCatchPattern":"try { await updater.UpdateAsync(...); }\ncatch (ProjectUpdaterException ex) when (ex.Message.Contains(\"could not be removed\"))\n{\n    // follow the message: remove the named <PackageVersion> entry from Directory.Packages.props manually\n}","preventionTips":["Close editors and builds that lock Directory.Packages.props before running `aspire update`.","Keep Directory.Packages.props under source control so you can diff/repair after a partial migration.","After any update, build once to catch NU1009 from leftover PackageVersion entries."],"tags":["aspire-cli","central-package-management","directory-packages-props","nu1009","partial-update"],"backgroundTag":"file-write-failed","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}