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
- Change RegistryKey to include hive and subkey separated by a backslash
- Use the installer's default value HKEY_CURRENT_USER\Software\Windhawk
- 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
- Always write RegistryKey as HIVE\SubKey
- Copy the installer's default value rather than composing your own
- Validate the format before persisting it
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
- Missing RegistryKey value
- Unsupported RegistryKey value
- Missing path value
- throw ResultException(failure)
- throw PortableSettingsException(error)
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)