ramensoftware/windhawk · error · SettingsError

RegDeleteValue

Error message

RegDeleteValue

What it means

This error surfaces the raw Windows registry return code when `RegDeleteValueW` fails for a reason other than success or ERROR_FILE_NOT_FOUND. The wrapper deliberately treats a missing value as success (idempotent remove); any other code (e.g. ERROR_ACCESS_DENIED, ERROR_KEY_DELETED) becomes a SettingsError named after the 'remove' operation.

Solutions

  1. Re-run the process elevated if the key is under HKLM/HKU protected areas
  2. Check the embedded Windows error code (rc) to identify the exact Win32 failure
  3. Verify the key handle is still valid and the key was not deleted concurrently
  4. Confirm the value name matches exactly (case is fine, but no stray NUL or invalid chars)

Example fix

// before
match settings.remove("MyValue") { Err(e) => panic!("{}", e), ... }
// after
match settings.remove("MyValue") {
    Ok(()) => {},
    Err(e) if e.is_access_denied() => eprintln!("elevate to remove protected value"),
    Err(e) => return Err(e.into()),
}
Defensive patterns

Strategy: try-catch

Validate before calling

if name.contains('\0') { return Err("value name contains NUL"); }

Try / catch

match settings.remove(name) {
    Ok(()) => {}, // includes already-absent values
    Err(e) => eprintln!("remove failed: {e}; check elevation/permissions"),
}

Prevention

When it happens

Trigger: Calling registry-backed settings `remove(name)` on a value the current process lacks delete rights for, or after the parent key handle has been invalidated/deleted; also value names with characters rejected by the registry beyond the wrapper's own NUL check.

Common situations: Trying to remove values under HKLM or other protected hives without elevation; antivirus or policy locking the key; another process deleted the key between opening and removing.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12). Data as JSON: /api/errors/e22d27a0e6273718. Report an issue: GitHub.

Appendix: source

Thrown at src/windhawk-core/windows/src/registry.rs:548

        })
    }

    fn set_binary(&mut self, name: &str, value: &[u8]) -> Result<(), SettingsError> {
        self.set_raw(name, REG_BINARY, value)
    }

    fn remove(&mut self, name: &str) -> Result<(), SettingsError> {
        self.check_name("remove", name)?;
        let Some(hkey) = self.hkey() else {
            return Ok(());
        };
        let name_w = to_wide(name);
        // SAFETY: name_w is NUL-terminated; hkey is a valid open key.
        let rc = unsafe { RegDeleteValueW(hkey, name_w.as_ptr()) };
        if rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND {
            Ok(())
        } else {
            Err(self.err("remove", rc, "RegDeleteValue"))
        }
    }

    fn enum_values(&self) -> Result<Vec<(String, TreeValue)>, SettingsError> {
        let Some(hkey) = self.hkey() else {
            return Ok(Vec::new());
        };
        let mut out = Vec::new();
        let mut index: u32 = 0;
        loop {
            // Value names are bounded at 16383 chars; +1 for the NUL.
            let mut name_buf = vec![0u16; 16384];
            let mut name_len = name_buf.len() as u32;
            // SAFETY: name_buf has name_len units; the data out params are
            // null (we re-read each value by name to type it uniformly).
            let rc = unsafe {
                RegEnumValueW(
                    hkey,

View on GitHub (pinned to 61d99ed8e1)