microsoft/aspire · error · InvalidOperationException
Integration assets file
Error message
Integration assets file '{assetsFilePath}' was not found after build. What it means
ReadPackageFingerprintsAsync parses the integration assets JSON file (produced by the bundled build) to collect package fingerprints. If the file is absent after the build, the build did not emit it, so the CLI throws InvalidOperationException naming the missing path. This is a post-build invariant: without the assets file there is no way to verify package integrity.
Solutions
- Verify the file exists at the exact path in the message and inspect the restore/build output directory.
- Re-run the bundled build and confirm it succeeds and emits the assets file.
- Align CLI and SDK versions so both agree on the assets file name and location.
- Clear stale restore output and rebuild from scratch.
Example fix
// before
var fingerprints = await ReadPackageFingerprintsAsync(assetsFilePath, ct);
// after: confirm the build emitted it
if (!File.Exists(assetsFilePath)) { throw new InvalidOperationException($"Bundle build did not emit assets file {assetsFilePath}"); } Defensive patterns
Strategy: validation
Validate before calling
if (!File.Exists(assetsFilePath))
throw new InvalidOperationException($"Assets file {assetsFilePath} missing — build did not emit it."); Type guard
static bool AssetsFileExists(string path) => File.Exists(path) && new FileInfo(path).Length > 0;
Try / catch
try { fingerprints = await ReadPackageFingerprintsAsync(assetsFilePath, ct); }
catch (InvalidOperationException ex) when (ex.Message.Contains("assets file"))
{ logger.LogError(ex, "Assets file missing; rebuilding bundle"); await RebuildAsync(ct); } Prevention
- Verify build success (exit code 0) before reading post-build artifacts.
- Don't clean intermediate directories between build and consumption.
- Keep CLI/SDK versions aligned so the assets file name/location matches expectations.
- List the restore directory after build to confirm expected outputs exist.
When it happens
Trigger: Loading package fingerprints after the bundled restore/build when the build skipped or failed to emit the assets JSON; the computed assetsFilePath points to the wrong directory; an SDK/CLI version mismatch changed the assets file name or location.
Common situations: Build step silently failed or was skipped; intermediate output cleaned by a tool; running a newer CLI against an older bundle layout; misconfigured restoreDir so the path differs from where the build wrote output.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Integration closure manifest file
- Failed to parse JSON output into type
- Integration closure manifest is inconsistent. Sources
- The CLI bundle layout was found, but the dashboard binary…
- The configuration file
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/a2e4c081a3ffd8eb.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs:1589
}
return new ClosureMetadata(
NormalizeClosureMetadataValue(parts[0]),
NormalizeClosureMetadataValue(parts[1]),
NormalizeClosureMetadataValue(parts[2]),
NormalizeClosureMetadataValue(parts[3]));
}
private static string? NormalizeClosureMetadataValue(string value)
{
return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
}
private static async Task<Dictionary<string, string>> ReadPackageFingerprintsAsync(string assetsFilePath, CancellationToken cancellationToken)
{
if (!File.Exists(assetsFilePath))
{
throw new InvalidOperationException($"Integration assets file '{assetsFilePath}' was not found after build.");
}
await using var stream = File.OpenRead(assetsFilePath);
using var document = await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken).ConfigureAwait(false);
var packageFingerprints = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
if (!document.RootElement.TryGetProperty("libraries", out var libraries))
{
return packageFingerprints;
}
foreach (var library in libraries.EnumerateObject())
{
cancellationToken.ThrowIfCancellationRequested();
if (!library.Value.TryGetProperty("type", out var typeElement) ||
!string.Equals(typeElement.GetString(), "package", StringComparison.OrdinalIgnoreCase) ||
!library.Value.TryGetProperty("sha512", out var sha512Element))View on GitHub (pinned to 25830f84bd)