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
- Re-run the process elevated if the key is under HKLM/HKU protected areas
- Check the embedded Windows error code (rc) to identify the exact Win32 failure
- Verify the key handle is still valid and the key was not deleted concurrently
- 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
- Run elevated when touching HKLM/HKU protected values
- Treat ERROR_FILE_NOT_FOUND as success — the wrapper already does
- Don't delete the parent key while values are being removed
- Log the embedded Win32 code for diagnosis
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
- RegEnumValue
- throw PortableSettingsException(error)
- GetPrivateProfileString
- value name contains a NUL
- RegQueryValueEx (size)
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)