{"record":{"id":"ad1259521037fc8b","repo":"microsoft/aspire","slug":"an-interaction-with-id-interactionupdate-interactionid","errorCode":null,"errorMessage":"An interaction with ID {interactionUpdate.InteractionId} already exists. Interaction IDs must be unique.","messagePattern":"An interaction with ID (.+?) already exists\\. Interaction IDs must be unique\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/InteractionService.cs","lineNumber":442,"sourceCode":"        lock (_onInteractionUpdatedLock)\n        {\n            var updateEvent = false;\n\n            if (interactionUpdate.State == Interaction.InteractionState.Complete)\n            {\n                Debug.Assert(\n                    interactionUpdate.CompletionTcs.Task.IsCompleted,\n                    \"TaskCompletionSource should be completed when interaction is done.\");\n\n                // Only update event if interaction was previously registered and not already removed.\n                updateEvent = _interactionCollection.Remove(interactionUpdate.InteractionId);\n            }\n            else\n            {\n                if (_interactionCollection.Contains(interactionUpdate.InteractionId))\n                {\n                    // Should never happen, but throw descriptive exception if it does.\n                    throw new InvalidOperationException($\"An interaction with ID {interactionUpdate.InteractionId} already exists. Interaction IDs must be unique.\");\n                }\n\n                _interactionCollection.Add(interactionUpdate);\n                updateEvent = true;\n            }\n\n            if (updateEvent)\n            {\n                OnInteractionUpdated?.Invoke(interactionUpdate);\n            }\n        }\n    }\n\n    internal void UpdateInteraction(Interaction interaction)\n    {\n        lock (_onInteractionUpdatedLock)\n        {\n            // Double check interaction is still in collection after awaiting the result creation.","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/InteractionService.cs#L424-L460","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nservice.AddInteractionUpdate(new InteractionUpdate { InteractionId = existingId, ... });\n// after\nvar id = Guid.NewGuid().ToString();\nservice.AddInteractionUpdate(new InteractionUpdate { InteractionId = id, ... });","handlingStrategy":"try-catch","validationCode":"if (service.ContainsInteraction(interactionUpdate.InteractionId)) // or check your own tracking set\n{\n    // update the existing interaction instead of adding a new one\n    return;\n}","typeGuard":"static bool IsNewInteraction(ISet<string> seenIds, string id) => seenIds.Add(id); // false when already seen","tryCatchPattern":"try\n{\n    service.AddInteractionUpdate(interactionUpdate);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"already exists\"))\n{\n    logger.LogError(ex, \"Duplicate interaction ID {Id}\", interactionUpdate.InteractionId);\n}","preventionTips":["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."],"tags":["duplicate-id","interaction-service","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}