microsoft/aspire · error · ArgumentException
The launch configuration callback context belongs to…
Error message
The launch configuration callback context belongs to resource '{context.Resource.Name}', but launch configuration was requested for resource '{resource.Name}'. What it means
CreateLaunchConfigurationAsync validates that the resource passed to it is the exact same instance as the resource carried by the LaunchConfigurationCallbackContext, since the context's callbacks and environment were built for that specific resource. When they differ, it throws ArgumentException on the context parameter naming both resources. This catches mismatches early instead of producing launch configuration for the wrong resource.
Solutions
- Pass the exact resource instance stored in context.Resource (pass context.Resource itself, or look up the matching context for the resource).
- Key contexts by resource instance, not by name, to avoid mismatched pairs.
- Recreate the callback context for the new resource instance if the model changed.
Example fix
// before
foreach (var r in model.Resources)
var cfg = await context.Resource.CreateLaunchConfigurationAsync(context); // wrong pairing
// after
var cfg = await resource.CreateLaunchConfigurationAsync(context); // context.Resource == resource Defensive patterns
Strategy: validation
Validate before calling
if (!ReferenceEquals(resource, context.Resource))
throw new InvalidOperationException($"Context belongs to '{context.Resource.Name}' but was paired with '{resource.Name}'."); Try / catch
try
{
var cfg = await resource.CreateLaunchConfigurationAsync(context, ct);
}
catch (ArgumentException ex) when (ex.ParamName == nameof(context))
{
logger.LogError(ex, "Launch context/resource mismatch: {Message}", ex.Message);
throw;
} Prevention
- Always pass context.Resource (or look up the context keyed by the resource instance) — never a different resource.
- Key launch contexts by resource instance (reference equality) rather than by name.
- Rebuild contexts after any model regeneration instead of reusing them for new instances.
- Add a debug assert for ReferenceEquals(resource, context.Resource) in orchestrator code.
When it happens
Trigger: Calling CreateLaunchConfigurationAsync(context, resource) where resource is a different resource object than context.Resource — e.g. iterating over one collection of resources while holding contexts created for another, or re-creating resource instances so reference equality fails.
Common situations: Custom orchestrators or test harnesses wiring launch contexts to a rebuilt/cloned resource model; storing contexts in a dictionary keyed by name and passing the wrong entry; after hot reload or model regeneration where the resource instance was replaced.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Resource ' ' does not declare debug launch support. Call…
- The " " launch configuration producer for resource ' '…
- AllocatedEndpoint must use the same network as the…
- Anonymous volumes cannot be read-only.
- Bind mounts must specify a source path.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/fd7e04f27852d5d6.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting/ApplicationModel/DebugSupportExtensions.cs:173
/// <para>
/// This method never resolves environment variables. Aspire creates <paramref name="context"/>
/// when the active debug-support annotation is producing a launch configuration for an executable creation.
/// </para>
/// <para>
/// This overload is internal because only Aspire constructs callback contexts containing resolved environment
/// variables. Use the public overload when inspecting a launch configuration outside executable creation.
/// </para>
/// </remarks>
internal static Task<object> CreateLaunchConfigurationAsync(
this IResource resource,
LaunchConfigurationCallbackContext context)
{
ArgumentNullException.ThrowIfNull(resource);
ArgumentNullException.ThrowIfNull(context);
if (!ReferenceEquals(resource, context.Resource))
{
throw new ArgumentException(
$"The launch configuration callback context belongs to resource '{context.Resource.Name}', " +
$"but launch configuration was requested for resource '{resource.Name}'.",
nameof(context));
}
if (!resource.TryGetLastAnnotation<SupportsDebuggingAnnotation>(out var supportsDebuggingAnnotation))
{
throw new InvalidOperationException(
$"Resource '{resource.Name}' does not declare debug launch support. " +
$"Call {nameof(ResourceBuilderExtensions.WithDebugSupport)} on the resource first. " +
$"Note that it only adds the annotation in run mode.");
}
return supportsDebuggingAnnotation.LaunchConfigurationProducer(context);
}
private static string[]? GetSupportedLaunchConfigurations(IConfiguration configuration)
{View on GitHub (pinned to 25830f84bd)