microsoft/aspire · error · InvalidOperationException
Toolbox ' ' changed concurrently: default version ' ' is…
Error message
Toolbox '{name}' changed concurrently: default version '{state.DefaultVersion}' is not managed by Aspire. No further changes were made. What it means
ValidateOwnedDefault checks whether the Toolbox's current default version carries Aspire management metadata. When invoked during a concurrent-change check (concurrentChange: true) the default not being Aspire-managed throws this error, meaning the Toolbox survived but its default was repointed to a version Aspire did not create or no longer controls. In the non-concurrent path the same condition yields the 'already exists but is not managed by Aspire' error instead. Either way, Aspire refuses to proceed rather than silently operating on an unmanaged default.
Solutions
- Identify the unmanaged default version in the Foundry portal and either re-promote the Aspire-managed version as default or let Aspire re-run the reconcile to restore it
- Stop external tooling or manual portal edits that repoint the default while Aspire deploys
- If the new default is intentional, adopt it deliberately by declaring that version in your AppHost so Aspire manages it
- Re-run the deploy; if it recurs, inspect who/what is mutating the Toolbox between operations
Example fix
// before: default repointed manually to unmanaged version '9.9.9'
// after: declare the intended managed version in the AppHost
#pragma warning disable ASPIREFOUNDRY001
cbuilder.AddFoundryToolbox("my-toolbox", version: "1.3.0"); Defensive patterns
Strategy: validation
Validate before calling
// Detect unmanaged defaults before deploying
var state = await administration.GetAsync(name, ct);
bool defaultIsManaged = state?.Versions.FirstOrDefault(v => v.Version == state.DefaultVersion)
?.Metadata.ContainsKey("aspire.managed") ?? false;
if (state is not null && !defaultIsManaged)
throw new InvalidOperationException($"Toolbox '{name}' default is not Aspire-managed; adopt or repoint it first."); Type guard
bool IsAspireManagedDefault(FoundryToolboxState state) =>
state.Versions.FirstOrDefault(v => v.Version == state.DefaultVersion)?.Metadata.Count > 0; Try / catch
try
{
await reconciler.ReconcileAsync(definition, ct);
}
catch (InvalidOperationException)
{
// Toolbox default was repointed by an external actor.
// Decide: adopt the new version in the AppHost, or restore via redeploy.
} Prevention
- Manage Toolbox versions exclusively through the AppHost, not the portal
- Audit the Toolbox default version before scheduled deploys
- Restrict portal write access to the deployment identity
When it happens
Trigger: PromoteOwnedVersionAsync or VerifyReusedDefaultAsync re-reads a Toolbox after promotion/during reconcile and finds state.DefaultVersion points at a version without Aspire ownership metadata; thrown when concurrentChange is true (i.e., the resource was Aspire-managed earlier in the same operation).
Common situations: Someone manually creates/promotes a new Toolbox version in the Foundry portal and sets it as default while a deploy is in flight; an external tool (script, IaC) repoints the default; a partially-failed external rollout leaves an unmanaged version as default.
Related errors
- Toolbox ' ' changed concurrently: target version ' ' is no…
- Toolbox ' ' changed concurrently: version ' ' was promoted…
- Toolbox ' ' changed concurrently: target version ' ' no…
- Toolbox ' ' changed concurrently: the Toolbox was no longer…
- Azure operation ' ' is already running or queued for the…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/fd3964af5ae38665.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Foundry/Toolbox/FoundryToolboxReconciler.cs:474
throw CreateConcurrentChangeException(
definition.Name,
$"version '{version}' was promoted, but version '{after.DefaultVersion}' is now the default");
}
}
private static void ValidateOwnedDefault(
string name,
FoundryToolboxState state,
bool concurrentChange = false)
{
if (IsAspireManaged(state.Default))
{
return;
}
if (concurrentChange)
{
throw CreateConcurrentChangeException(
name,
$"default version '{state.DefaultVersion}' is not managed by Aspire");
}
throw new InvalidOperationException(
$"Toolbox '{name}' already exists but is not managed by Aspire. No changes were made.");
}
private static void ValidatePromotionTarget(
FoundryToolboxDeploymentDefinition definition,
FoundryToolboxState state,
string version)
{
var target = state.Versions.FirstOrDefault(candidate =>
string.Equals(candidate.Version, version, StringComparison.Ordinal));
if (target is null)
{
throw CreateConcurrentChangeException(View on GitHub (pinned to 25830f84bd)