{"record":{"id":"09bdea2264f693b5","repo":"stride3d/stride","slug":"the-provided-sound-is-not-currently-attached-to-this-emitter","errorCode":null,"errorMessage":"The provided Sound is not currently attached to this emitter component.","messagePattern":"The provided Sound is not currently attached to this emitter component\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Engine/Engine/AudioEmitterComponent.cs","lineNumber":164,"sourceCode":"            var newController = new AudioEmitterSoundController(this, sound);\n            SoundToController[sound] = newController;\n            ControllerCollectionChanged?.Invoke(this, new ControllerCollectionChangedEventArgs(Entity, newController, this, NotifyCollectionChangedAction.Add));\n\n            return newController;\n        }\n\n        /// <summary>\n        /// Detach a <see cref=\"SoundBase\"/> from this emitter component.\n        /// Once detach the controller previously associated to the SoundBase is invalid.\n        /// </summary>\n        /// <param name=\"sound\">The SoundBase to detach.</param>\n        /// <exception cref=\"ArgumentNullException\">The provided <paramref name=\"sound\"/> is null.</exception>\n        /// <exception cref=\"ArgumentException\">The provided <paramref name=\"sound\"/> is not currently attached to the emitter component.</exception>\n        public void DetachSound([NotNull] SoundBase sound)\n        {\n            if (sound == null) throw new ArgumentNullException(nameof(sound));\n            if (!SoundToController.ContainsKey(sound))\n                throw new ArgumentException(\"The provided Sound is not currently attached to this emitter component.\");\n\n            var oldController = SoundToController[sound];\n            SoundToController.Remove(sound);\n            ControllerCollectionChanged?.Invoke(this, new ControllerCollectionChangedEventArgs(Entity, oldController, this, NotifyCollectionChangedAction.Remove));\n        }\n\n        private void SoundAdded(SoundBase sound)\n        {\n            AttachSound(sound);\n            SoundMultiplicities.TryGetValue(sound, out var v);\n            SoundMultiplicities[sound] = v+1;\n        }\n\n        private void SoundRemoved(SoundBase sound)\n        {\n            var val = SoundMultiplicities[sound];\n            if (val == 1)\n            {","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Engine/Engine/AudioEmitterComponent.cs#L146-L182","documentation":"AudioEmitterComponent.DetachSound throws ArgumentException when the given sound has no controller registered in this emitter's SoundToController map, i.e. it was never attached (or was already detached). Detaching works only on sounds previously passed to AttachSound on the same component.","triggerScenarios":"Calling DetachSound with a sound attached to a different emitter, detaching twice, or detaching a sound that was removed via the Sound collection before DetachSound ran.","commonSituations":"Component teardown code detaching sounds already cleaned up, entity hierarchy changes removing sounds automatically (SoundRemoved), or confusion between two AudioEmitterComponents on different entities.","solutions":["Guard with SoundToController.ContainsKey(sound) (or the public equivalent check) before detaching.","Only detach sounds you attached on this exact component instance; track attached sounds yourself.","Wrap in try/catch for ArgumentException if detach-on-teardown may run twice."],"exampleFix":"// before\nemitter.DetachSound(sound); // throws if never attached\n// after\nif (emitter.Controllers.Any(c => c.Sound == sound))\n    emitter.DetachSound(sound);","handlingStrategy":"try-catch","validationCode":"if (emitter.Controllers.Any(c => c.Sound == sound))\n    emitter.DetachSound(sound);","typeGuard":null,"tryCatchPattern":"try { emitter.DetachSound(sound); }\ncatch (ArgumentException) { /* never attached or already detached; safe to ignore */ }","preventionTips":["Track which sounds you attached on which emitter instance.","Make teardown idempotent: tolerate already-detached sounds.","Do not share the same sound instance across emitter detach logic."],"tags":["audio","argument-validation","resource-not-found"],"backgroundTag":"resource-not-found","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}