Hmbown/CodeWhale · error

invalid sound path

Error message

invalid sound path

What it means

This error is thrown by NotificationConfigUpdate::parse when the value given for a sound file setting is not a usable path string: it must be non-empty, at most 4096 bytes, and contain no control characters. It guards against empty, oversized, or corrupted path values reaching the notification sound player.

Solutions

  1. Set the sound value to a non-empty absolute or relative path to an existing audio file, e.g. "/usr/share/sounds/bell.ogg".
  2. Remove any control characters (newlines, NULs, escapes) from the path string.
  3. Shorten the path — move the sound file to a shallower directory so the path is under 4096 bytes.
  4. If you meant a built-in sound name rather than a file, use the corresponding non-file setting instead of SoundFile.

Example fix

// before
sound = ""
// after
sound = "/usr/share/sounds/freedesktop/stereo/bell.oga"
Defensive patterns

Strategy: validation

Validate before calling

fn valid_sound_path(s: &str) -> bool {
    !s.is_empty() && s.len() <= 4096 && !s.chars().any(char::is_control)
}

Try / catch

match update.validate() {
    Err(e) if e.to_string().contains("invalid sound path") => eprintln!("fix the sound path in config: {e}"),
    other => other?,
}

Prevention

When it happens

Trigger: Calling NotificationConfigUpdate::parse with K::Sound where the raw TOML value is a string that is empty, longer than 4096 characters/bytes, or contains control characters (e.g. embedded \n, \0, or escape sequences that decode to control bytes).

Common situations: A user leaves sound = "" in the config; a config generator writes a path with a trailing newline or NUL byte; an overly long path from a deep directory tree exceeds 4096 bytes.

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


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/a5dec76a762d4cb4. Report an issue: GitHub.

Appendix: source

Thrown at crates/config/src/notifications.rs:241

            ),
            K::SubagentCompletion => Self::SubagentCompletion(
                SubagentCompletionNotification::parse(raw)
                    .context("invalid subagent notification policy")?,
            ),
            K::SoundFile => {
                let value = raw.trim();
                let value = if value.starts_with(['\'', '"']) {
                    let parsed: toml::Table = toml::from_str(&format!("value = {value}"))
                        .context("invalid quoted sound path")?;
                    parsed
                        .get("value")
                        .and_then(toml::Value::as_str)
                        .context("expected sound path string")?
                        .to_string()
                } else {
                    value.to_string()
                };
                anyhow::ensure!(
                    !value.is_empty()
                        && value.len() <= 4096
                        && !value.chars().any(char::is_control),
                    "invalid sound path"
                );
                Self::SoundFile(PathBuf::from(value))
            }
            K::Event(event) => Self::Event(event, boolean()?),
            K::EventSoundEnabled => Self::EventSoundEnabled(boolean()?),
            K::EventSoundQuiet => Self::EventSoundQuiet(boolean()?),
            K::EventSoundMinIntervalMs => Self::EventSoundMinIntervalMs(integer()?),
            K::EventSoundEvents => {
                anyhow::ensure!(raw.len() <= 1024, "notification event list is too large");
                let parsed: toml::Table = toml::from_str(&format!("events = {raw}"))
                    .context("expected TOML notification event array")?;
                let values = parsed
                    .get("events")
                    .and_then(toml::Value::as_array)

View on GitHub (pinned to 73e0f67d83)