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

  1. Stop any running AppHost or process that could hold files in the staged dependency directory, then rerun the command
  2. Delete the named directory manually and rerun
  3. 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

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


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)