{"record":{"id":"1f1d237a2604db05","repo":"Hmbown/CodeWhale","slug":"invalid-or-duplicate-notification-event","errorCode":null,"errorMessage":"invalid or duplicate notification event","messagePattern":"invalid or duplicate notification event","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/config/src/notifications.rs","lineNumber":313,"sourceCode":"    pub fn validate(&self) -> Result<()> {\n        match self {\n            Self::ThresholdSecs(v) | Self::EventSoundMinIntervalMs(v) => anyhow::ensure!(\n                *v <= i64::MAX as u64,\n                \"notification integer exceeds TOML range\"\n            ),\n            Self::SoundFile(path) => {\n                let value = path.to_str().context(\"sound path must be UTF-8\")?;\n                anyhow::ensure!(\n                    !value.is_empty()\n                        && value.len() <= 4096\n                        && !value.chars().any(char::is_control),\n                    \"invalid sound path\"\n                );\n            }\n            Self::EventSoundEvents(events) => {\n                anyhow::ensure!(events.len() <= 6, \"too many notification events\");\n                for (index, event) in events.iter().enumerate() {\n                    anyhow::ensure!(\n                        NotificationEvent::parse(event).is_some()\n                            && !events[..index].contains(event),\n                        \"invalid or duplicate notification event\"\n                    );\n                }\n            }\n            _ => (),\n        }\n        Ok(())\n    }\n    pub fn value(&self) -> Result<Option<toml::Value>> {\n        self.validate()?;\n        Ok(Some(match self {\n            Self::Method(value) => value.as_str().into(),\n            Self::Sound(Some(value)) | Self::CompletionSound(value) => value.as_str().into(),\n            Self::Sound(None) => return Ok(None),\n            Self::Condition(value) => value.as_str().into(),\n            Self::SubagentCompletion(value) => value.as_str().into(),","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/config/src/notifications.rs#L295-L331","documentation":"This error is thrown by NotificationConfigUpdate::validate when any entry in an EventSoundEvents list is not a recognized notification event name, or when the same event name appears more than once in the list. NotificationEvent::parse must accept each name, and each must be unique within the list.","triggerScenarios":"Constructing NotificationConfigUpdate::EventSoundEvents with a list containing an unrecognized event string (e.g. a typo like \"turn_complte\") or a duplicated name, then calling validate() via value(), persist_for_profile(), edit_extras(), or apply_update().","commonSituations":"Hand-edited config with misspelled event names; case mismatches (parser is exact); a generator appends events without checking for existing entries, producing duplicates; event names renamed between versions.","solutions":["Check each name against the accepted NotificationEvent names (exact match, correct spelling/case).","Deduplicate the list before constructing the update.","If an event name was renamed in a newer version, update the config to the new name.","Use NotificationEvent::parse in your own code to validate names before building the list."],"exampleFix":"// before\nNotificationConfigUpdate::EventSoundEvents(vec![\"turn-complete\".into(), \"turn-complete\".into()])\n// after\nNotificationConfigUpdate::EventSoundEvents(vec![\"turn-complete\".into(), \"error\".into()])","handlingStrategy":"validation","validationCode":"fn valid_event_names(events: &[String]) -> bool {\n    events.iter().all(|e| NotificationEvent::parse(e).is_some())\n        && events.iter().collect::<std::collections::HashSet<_>>().len() == events.len()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate each name with NotificationEvent::parse before building the list","Copy event names exactly (case-sensitive) from the documented set","Deduplicate lists before persisting","Watch for renamed events across library versions"],"tags":["config","invalid-enum","duplicate"],"backgroundTag":"invalid-enum-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}