ramensoftware/windhawk · error · std::runtime_error

Missing RegistryKey value

Error message

Missing RegistryKey value

What it means

In non-portable mode, StorageManager's constructor reads the "RegistryKey" value that says where settings live in the registry. If that value is empty or absent, the manager cannot determine its settings location and throws immediately.

Solutions

  1. Set the RegistryKey value (e.g. HKEY_CURRENT_USER\Software\Windhawk) in the bootstrap storage
  2. Repair/reinstall Windhawk so the installer writes the default RegistryKey
  3. If portable use is intended, enable portable mode so the INI path branch is taken instead
  4. Back up and restore registry values if group policy or scripts strip them

Example fix

// before: bootstrap storage
"RegistryKey": ""
// 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()) { repairBootstrapStorage(); }

Try / catch

try {
    StorageManager sm(/*portableStorage=*/false);
} catch (const std::exception& e) {
    Log(L"storage init failed: %hs", e.what());
}

Prevention

When it happens

Trigger: Constructing StorageManager with portableStorage == false when storage.GetString(L"RegistryKey") returns nothing or an empty string.

Common situations: Registry value deleted by cleanup tools or manual edits; migration between portable and installed mode leaving the key unset; corrupted bootstrap storage.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

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

    enginePath = PathFromStorage(storage, L"EnginePath", folderPath);
    uiPath = PathFromStorage(storage, L"UIPath", folderPath, /*optional=*/true);
    compilerPath = PathFromStorage(storage, L"CompilerPath", folderPath,
                                   /*optional=*/true);
    appDataPath = PathFromStorage(storage, L"AppDataPath", folderPath);

    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");

View on GitHub (pinned to 61d99ed8e1)