microsoft/aspire · error · InvalidOperationException
An interaction with ID
Error message
An interaction with ID {interactionUpdate.InteractionId} already exists. Interaction IDs must be unique. What it means
InteractionService.AddInteractionUpdate enforces unique interaction IDs in its internal collection. When an update carries an InteractionId that is already registered (and is not a recognized replacement of an existing interaction), it throws InvalidOperationException; the code comment notes this should never happen in normal operation.
Solutions
- Generate a fresh unique InteractionId (GUID) for each new interaction update.
- Check _interactionCollection.Contains(id) / the service's API before adding and update the existing interaction instead.
- Fix retry/replay logic so duplicates are deduplicated before calling AddInteractionUpdate.
Example fix
// before
service.AddInteractionUpdate(new InteractionUpdate { InteractionId = existingId, ... });
// after
var id = Guid.NewGuid().ToString();
service.AddInteractionUpdate(new InteractionUpdate { InteractionId = id, ... }); Defensive patterns
Strategy: try-catch
Validate before calling
if (service.ContainsInteraction(interactionUpdate.InteractionId)) // or check your own tracking set
{
// update the existing interaction instead of adding a new one
return;
} Type guard
static bool IsNewInteraction(ISet<string> seenIds, string id) => seenIds.Add(id); // false when already seen
Try / catch
try
{
service.AddInteractionUpdate(interactionUpdate);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("already exists"))
{
logger.LogError(ex, "Duplicate interaction ID {Id}", interactionUpdate.InteractionId);
} Prevention
- Generate a fresh GUID for every new interaction update.
- Track issued IDs in a HashSet and skip or merge duplicates before adding.
- Do not replay or retry AddInteractionUpdate with the same update object.
When it happens
Trigger: Calling AddInteractionUpdate manually with a reused ID, or a lifecycle bug where the same interaction update is enqueued twice (e.g. re-invoking PromptMessageBoxCoreAsync/PromptInputsAsync paths with a stale interactionUpdate whose ID collides).
Common situations: Custom dashboard/CLI interaction consumers re-submitting updates; retry logic replaying an already-added update; concurrency bugs where two callbacks create updates with the same ID.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- A validation message must be provided for a failed…
- ConnectionStringAvailableEvent was published for the
- ConnectionStringAvailableEvent was published for the
- ConnectionStringAvailableEvent was published for the
- Container tunnel service
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/ad1259521037fc8b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting/InteractionService.cs:442
lock (_onInteractionUpdatedLock)
{
var updateEvent = false;
if (interactionUpdate.State == Interaction.InteractionState.Complete)
{
Debug.Assert(
interactionUpdate.CompletionTcs.Task.IsCompleted,
"TaskCompletionSource should be completed when interaction is done.");
// Only update event if interaction was previously registered and not already removed.
updateEvent = _interactionCollection.Remove(interactionUpdate.InteractionId);
}
else
{
if (_interactionCollection.Contains(interactionUpdate.InteractionId))
{
// Should never happen, but throw descriptive exception if it does.
throw new InvalidOperationException($"An interaction with ID {interactionUpdate.InteractionId} already exists. Interaction IDs must be unique.");
}
_interactionCollection.Add(interactionUpdate);
updateEvent = true;
}
if (updateEvent)
{
OnInteractionUpdated?.Invoke(interactionUpdate);
}
}
}
internal void UpdateInteraction(Interaction interaction)
{
lock (_onInteractionUpdatedLock)
{
// Double check interaction is still in collection after awaiting the result creation.View on GitHub (pinned to 25830f84bd)