microsoft/aspire · error · InvalidOperationException
Multiple NuGet.config files found in
Error message
Multiple NuGet.config files found in '{directory.FullName}' differing only by case. What it means
NuGetConfigMerger scans a directory (top-level only) for files named nuget.config case-insensitively; if it finds more than one that differ only by case (e.g. NuGet.config and nuget.config), it throws because the correct file to merge into is ambiguous. The merge refuses to guess which config to modify.
Solutions
- Delete or rename one of the duplicate configs so only a single `nuget.config` remains.
- Merge the contents of both files into one canonical `NuGet.config`.
- Use `git ls-files | grep -i nuget.config` to find case-duplicated files tracked by git.
- On git, fix tracked casing with `git mv -f nuget.config NuGet.config` if the wrong casing is committed.
Example fix
// before (directory contains NuGet.config AND nuget.config) // after: keep one canonical file // git mv -f nuget.config NuGet.config // git commit -m "Deduplicate NuGet.config casing"
Defensive patterns
Strategy: validation
Validate before calling
var dupes = Directory.EnumerateFiles(dir, "*", SearchOption.TopDirectoryOnly)
.Where(f => string.Equals(Path.GetFileName(f), "nuget.config", StringComparison.OrdinalIgnoreCase))
.ToList();
if (dupes.Count > 1) throw new InvalidOperationException($"Multiple NuGet.config casings found: {string.Join(", ", dupes)}"); Try / catch
try
{
await merger.MergeAsync(targetDir, sources, ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Multiple NuGet.config files"))
{
Console.Error.WriteLine("Deduplicate NuGet.config casings before merging.");
} Prevention
- Standardize on one casing (NuGet.config) repo-wide
- On Windows/macOS, check git for case-only duplicates before pushing to Linux CI
- Add a CI lint that fails on case-ambiguous config filenames
When it happens
Trigger: Running any NuGetConfigMerger operation (Create/merge flow) in a project or directory that contains both `NuGet.config` and `nuget.config` (or `NUGET.CONFIG`, etc.) at the top level.
Common situations: A repo created on a case-insensitive OS (Windows/macOS) later checked out on Linux showing both casings; manual edits adding a second config with different casing; tooling generated one and a developer hand-added another.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- aspire-managed not found in layout.
- aspire-managed not found in layout.
- ASPIRERADIUS052
- Assets file not found
- Browser user data directory
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/aad6531b39f2d0e4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Cli/Packaging/NuGetConfigMerger.cs:935
catch
{
// If we can't read the file, assume sources are missing
return true;
}
}
internal static bool TryFindNuGetConfigInDirectory(DirectoryInfo directory, [NotNullWhen(true)] out FileInfo? nugetConfigFile)
{
ArgumentNullException.ThrowIfNull(directory);
// Find all files whose name matches "nuget.config" ignoring case in the top-level directory only
var matches = directory
.EnumerateFiles("*", SearchOption.TopDirectoryOnly)
.Where(f => string.Equals(f.Name, "nuget.config", StringComparison.OrdinalIgnoreCase))
.ToArray();
if (matches.Length > 1)
{
throw new InvalidOperationException($"Multiple NuGet.config files found in '{directory.FullName}' differing only by case.");
}
nugetConfigFile = matches.SingleOrDefault();
return matches.Length == 1;
}
private static async Task AddGlobalPackagesFolderToConfigAsync(FileInfo configFile)
{
XDocument doc;
await using (var stream = configFile.OpenRead())
{
doc = XDocument.Load(stream);
}
var configuration = doc.Root ?? throw new InvalidOperationException("Invalid NuGet config structure");
AddGlobalPackagesFolderConfiguration(configuration);
await using (var writeStream = configFile.Open(FileMode.Create, FileAccess.Write, FileShare.None))View on GitHub (pinned to 25830f84bd)