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

  1. Generate a fresh unique InteractionId (GUID) for each new interaction update.
  2. Check _interactionCollection.Contains(id) / the service's API before adding and update the existing interaction instead.
  3. 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

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


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)