Hmbown/CodeWhale · error
ConfigCommandInvalidValue
ConfigCommandInvalidValue
Error message
notifications.{key}: {value} (choices: {choices}) What it means
apply_notification_update applies a NotificationConfigUpdate to the live notifications config. When notifications.apply_update rejects the value (invalid setting or out-of-choice value), the error message is localized (MessageId::ConfigCommandInvalidValue) and interpolated with the setting key, the unusable value, and the accepted choices list. It carries code ConfigCommandInvalidValue so the config-command layer can classify it.
Solutions
- Use one of the listed choices shown in the error message when setting notifications.<key>.
- Validate the value against setting.choices() before constructing NotificationConfigUpdate.
- If a live delta came from an edited config file, fix the offending value there and reload.
- Check for typos/case differences between the provided value and the enumerated choices.
Example fix
// before
let update = NotificationConfigUpdate::new("sound", user_value);
apply_notification_update(app, config, update)?;
// after — validate first
let update = NotificationConfigUpdate::new("sound", user_value);
if !update.setting().choices().split(',').any(|c| c.trim() == user_value) {
app.add_message(format!("notifications.sound must be one of: {}", update.setting().choices()));
return Ok(());
}
apply_notification_update(app, config, update)?; Defensive patterns
Strategy: validation
Validate before calling
let choices: Vec<&str> = setting.choices().split(',').map(str::trim).collect();
if !choices.contains(&provided_value.as_str()) {
return Err(anyhow!("notifications.{} must be one of: {}", setting.key(), setting.choices()));
} Type guard
fn is_valid_choice(value: &str, setting: &NotificationSetting) -> bool { setting.choices().split(',').any(|c| c.trim() == value) } Try / catch
match notifications.apply_update(update) {
Ok(()) => {},
Err(_) => show_localized_invalid_value(setting.key(), setting.choices()),
} Prevention
- Use the same enumerated strings shown in the error's choices list when setting notifications.* values.
- Validate external config edits against setting.choices() before applying live deltas.
- Watch for case sensitivity and whitespace in values passed to NotificationConfigUpdate.
When it happens
Trigger: Calling apply_notification_update (from apply_command_result or a live notification config delta) with an update whose value is not among setting.choices() — e.g. setting notifications.<key> to a string that isn't one of the allowed enumerated choices.
Common situations: Typing an invalid value in the config command (e.g. notifications.sound=bell when choices are on/off); live config deltas from external editors using stale or wrong value names; locale-dependent message rendering showing 'unavailable' for the bad value.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Can't use ' ' for . Try: .
- expected a notification boolean
- agent profile provider cannot be empty
- agent profile provider must be a simple provider id
- api_key cannot be empty string
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/5e09a46ac95ce6cd.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tui/ui/apply.rs:1272
// toggling the stale flag off.
app.voice_enabled = false;
}
let notice = app
.tr(MessageId::SettingLockedDuringTurn)
.replace("{setting}", "Codewhale Runtime");
app.push_status_toast(notice, crate::tui::app::StatusToastLevel::Info, Some(6_000));
true
}
pub(crate) fn apply_notification_update(
app: &mut App,
config: &mut Config,
update: crate::config::NotificationConfigUpdate,
) -> Result<()> {
let mut notifications = config.notifications_config();
let setting = update.setting();
notifications.apply_update(update).map_err(|_| {
anyhow::anyhow!(
app.tr(MessageId::ConfigCommandInvalidValue)
.replace("{key}", &format!("notifications.{}", setting.key()))
.replace("{value}", &app.tr(MessageId::ConfigUnavailable))
.replace("{choices}", setting.choices())
)
})?;
config.notifications = Some(notifications);
app.refresh_notification_settings(config);
Ok(())
}
pub(crate) async fn apply_command_result(
terminal: &mut AppTerminal,
app: &mut App,
engine_handle: &mut EngineHandle,
task_manager: &SharedTaskManager,
config: &mut Config,
result: commands::CommandResult,View on GitHub (pinned to 433685b202)