microsoft/aspire · error · InvalidOperationException
The staged dependency directory
Error message
The staged dependency directory '{dependencyDirectory}' could not be cleared, so the AppHost would run with both the old and new versions of any upgraded dependency on its classpath. Close anything holding files in that directory, or delete it manually, then run the command again. What it means
Before running an upgraded Java AppHost, ClearStagedDependencies wipes the staged dependency directory. If deletion fails with an IOException or UnauthorizedAccessException, the method throws rather than proceeding, because leaving stale JARs would put both old and new versions of an upgraded dependency on the classpath and cause hard-to-diagnose load-order bugs.
Solutions
- Stop any running AppHost or process that could hold files in the staged dependency directory, then rerun the command
- Delete the named directory manually and rerun
- Check/fix permissions on the directory (chmod or take ownership) if deletion was denied
Example fix
// before $ aspire run # error: staged dir locked by running AppHost // after $ kill <apphost pid> # or close the IDE-launched run $ rm -rf .aspire/staged/deps $ aspire run
Defensive patterns
Strategy: retry
Validate before calling
// Best-effort: ensure no live process pins the directory before invoking
var hasLocks = Directory.EnumerateFiles(dependencyDirectory, "*", SearchOption.AllDirectories)
.Any(f => { try { using var s = File.Open(f, FileMode.Open, FileAccess.Read, FileShare.None); return false; } catch (IOException) { return true; } }); Try / catch
try { resolver.ClearStagedDependencies(dir); }
catch (InvalidOperationException ex) when (ex.Message.Contains("could not be cleared"))
{
// stop running AppHosts, retry after delay
await Task.Delay(1000); retryOnce = true;
} Prevention
- Stop running AppHosts before upgrading/re-running commands that restage dependencies
- Exclude staging directories from antivirus/indexers where possible
- Run CLI commands as a user with write/delete access to the staging directory
When it happens
Trigger: Calling ClearStagedDependencies while another process (running AppHost, IDE, file indexer) holds files open in the dependency directory, or when the current user lacks delete permission on it.
Common situations: A previously launched AppHost still running and locking JARs (Windows), an IDE or antivirus scanning the directory, or read-only permissions after copying artifacts.
Related errors
- The filesystem spelling of
- ArgumentOutOfRangeException: Specified argument was out of…
- ArgumentOutOfRangeException: Specified argument was out of…
- ArgumentOutOfRangeException: Specified argument was out of…
- ASPIRE_REMOTE_APPHOST_TOKEN environment variable not set…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/195d0eb30a0fc259.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Cli/Projects/JavaAppHostToolchainResolver.cs:512
var dependencyDirectory = Path.Combine(
resolution.ProjectDirectory.FullName,
GetDependencyDirectory(resolution.Toolchain));
try
{
if (Directory.Exists(dependencyDirectory))
{
Directory.Delete(dependencyDirectory, recursive: true);
}
}
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException)
{
// Continuing here would defeat the only reason this method exists. Maven adds the new
// versioned JAR beside the stale one, both end up on the "dir/*" classpath, and which one
// the JVM loads is left to directory order — a failure that surfaces later as an unrelated
// NoSuchMethodError. Better to stop now with a message that names the directory.
throw new InvalidOperationException(
$"The staged dependency directory '{dependencyDirectory}' could not be cleared, so the " +
"AppHost would run with both the old and new versions of any upgraded dependency on its " +
"classpath. Close anything holding files in that directory, or delete it manually, then " +
"run the command again.",
ex);
}
}
/// <summary>
/// Path from the AppHost directory to the project directory, or <see langword="null"/> when they are
/// the same. Null rather than "." so the common flat layout keeps clean, unprefixed relative paths.
/// </summary>
private static string? GetRelativeProjectPath(DirectoryInfo projectDirectory, DirectoryInfo appHostDirectory)
{
var relativePath = Path.GetRelativePath(appHostDirectory.FullName, projectDirectory.FullName);
return relativePath == "." ? null : relativePath;
}View on GitHub (pinned to 25830f84bd)