ramensoftware/windhawk · error · SettingsError

RegEnumValue

Error message

RegEnumValue

What it means

This error is raised when `RegEnumValueW` returns a code other than ERROR_SUCCESS or ERROR_NO_MORE_ITEMS while iterating a registry key's values. It aborts the value enumeration of settings stored in the registry, wrapping the raw Win32 return code in a SettingsError.

Solutions

  1. Re-open the key and retry the enumeration
  2. Check the wrapped Win32 return code for the specific failure
  3. Ensure the key handle was opened with KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS rights
  4. Avoid deleting values from the key concurrently with enumeration

Example fix

// before
let values = settings.enum_values()?;
// after
let values = match settings.enum_values() {
    Ok(v) => v,
    Err(e) => { log::warn!("registry enum failed: {e}; reopening key"); reopen_and_retry()? }
};
Defensive patterns

Strategy: retry

Validate before calling

// ensure the key exists and is readable before enumerating
// (RegQueryInfoKey on the same handle first is the Win32-level guard)

Try / catch

match settings.enum_values() {
    Ok(v) => v,
    Err(e) => { warn!("enum failed ({e}); reopening key"); reopen_key()?.enum_values()? }
}

Prevention

When it happens

Trigger: Enumerating values of a key whose handle became invalid (ERROR_KEY_DELETED / ERROR_INVALID_HANDLE), or a key with a value whose metadata cannot be read due to registry corruption or concurrent modification.

Common situations: Another process deletes or rewrites the key while settings are being listed; registry hives corrupted; handle opened with insufficient rights to query values.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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

Appendix: source

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

            // 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,
                    index,
                    name_buf.as_mut_ptr(),
                    &mut name_len,
                    std::ptr::null(),
                    std::ptr::null_mut(),
                    std::ptr::null_mut(),
                    std::ptr::null_mut(),
                )
            };
            if rc == ERROR_NO_MORE_ITEMS {
                break;
            }
            if rc != ERROR_SUCCESS {
                return Err(self.err("enum", rc, "RegEnumValue"));
            }
            name_buf.truncate(name_len as usize);
            let name = from_wide(&name_buf);
            if let Some((t, bytes)) = self.query_raw(&name)? {
                let value = if t == REG_SZ {
                    TreeValue::Str(decode_sz(&bytes))
                } else if t == REG_DWORD {
                    match decode_dword(&bytes) {
                        Some(i) => TreeValue::Int(i),
                        None => {
                            index += 1;
                            continue;
                        }
                    }
                } else if t == REG_BINARY {
                    TreeValue::Binary(bytes)
                } else {
                    index += 1;

View on GitHub (pinned to 61d99ed8e1)