ramensoftware/windhawk · error · std::runtime_error

Invalid RegistryKey value

Error message

Invalid RegistryKey value

What it means

After confirming the RegistryKey value is non-empty, StorageManager requires it to contain a backslash separating the base hive (e.g. HKEY_CURRENT_USER) from the subkey. A value without any backslash cannot be split into hive + subkey, so the constructor throws.

Solutions

  1. Change RegistryKey to include hive and subkey separated by a backslash
  2. Use the installer's default value HKEY_CURRENT_USER\Software\Windhawk
  3. Validate the value format (contains one backslash) before writing it to storage

Example fix

// before
"RegistryKey": "HKEY_CURRENT_USER"
// after
"RegistryKey": "HKEY_CURRENT_USER\\Software\\Windhawk"
Defensive patterns

Strategy: validation

Validate before calling

std::wstring key = storage.GetString(L"RegistryKey").value_or(L"");
if (!key.empty() && key.find(L'\\') == std::wstring::npos) {
    throw std::runtime_error("RegistryKey must be HIVE\\SubKey");
}

Prevention

When it happens

Trigger: StorageManager constructor parses a non-empty RegistryKey string in which find(L'\\') returns npos — e.g. "HKEY_CURRENT_USER" with no subkey part.

Common situations: User typed only the hive name into the RegistryKey setting; value truncated during manual registry editing; documentation followed incorrectly.

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 ramensoftware/windhawk@61d99ed8e1 (2026-09-12). Data as JSON: /api/errors/557fed8ce3c13db3. Report an issue: GitHub.

Appendix: source

Thrown at src/windhawk/app/storage_manager.cpp:238

    if (!std::filesystem::is_directory(appDataPath)) {
        std::error_code ec;
        std::filesystem::create_directories(appDataPath, ec);
    }

    portableStorage = storage.GetInt(L"Portable").value_or(0);
    if (portableStorage) {
        settingsPath = IniFilePath{appDataPath / L"settings.ini"};
    } else {
        std::wstring registryKey =
            storage.GetString(L"RegistryKey").value_or(L"");
        if (registryKey.empty()) {
            throw std::runtime_error("Missing RegistryKey value");
        }

        auto firstBackslash = registryKey.find(L'\\');
        if (firstBackslash == registryKey.npos) {
            throw std::runtime_error("Invalid RegistryKey value");
        }

        HKEY hkey;

        std::wstring baseKey = registryKey.substr(0, firstBackslash);
        if (baseKey == L"HKEY_CURRENT_USER" || baseKey == L"HKCU") {
            hkey = HKEY_CURRENT_USER;
        } else if (baseKey == L"HKEY_USERS" || baseKey == L"HKU") {
            hkey = HKEY_USERS;
        } else if (baseKey == L"HKEY_LOCAL_MACHINE" || baseKey == L"HKLM") {
            hkey = HKEY_LOCAL_MACHINE;
        } else {
            throw std::runtime_error("Unsupported RegistryKey value");
        }

        std::wstring subKey = registryKey.substr(firstBackslash + 1);

        settingsPath = RegistryPath{hkey, std::move(subKey)};

View on GitHub (pinned to 61d99ed8e1)