ramensoftware/windhawk · error · std::runtime_error
Missing path value
Error message
Missing path value: {valueName} What it means
PathFromStorage reads a path-like string value from the settings storage and, unless the value is marked optional, throws when the stored value is empty or missing. It guards the constructor paths of StorageManager which must know where settings/engine data live before any operation can proceed.
Solutions
- Restore the missing value in the settings storage (settings.ini or the registry key)
- Reinstall or run Windhawk's repair to repopulate default storage values
- If the path is genuinely optional, mark the optional parameter true at the call site
- Compare against a working installation to find which valueName is absent
Example fix
// before: required key missing from settings.ini // [Paths] (ApplicationPath absent) // after // [Paths] ApplicationPath=C:\Program Files\Windhawk
Defensive patterns
Strategy: validation
Validate before calling
// confirm required values exist in storage before constructing StorageManager
for (auto name : requiredPathValues) {
if (storage.GetString(name).value_or(L"").empty()) throw std::runtime_error("setup incomplete");
} Try / catch
try {
StorageManager sm(portableStorage);
} catch (const std::exception& e) {
Log(L"storage init failed: %hs", e.what());
} Prevention
- Never remove path keys from settings.ini or the registry store
- Run the installer/repair after manual storage cleanup
- Mark truly optional paths with optional=true at the call site
When it happens
Trigger: StorageManager::StorageManager or StorageManager::GetEngineAppDataPath calling PathFromStorage with a non-optional valueName (e.g. an AppData path key) when storage.GetString(valueName) returns nothing or an empty string.
Common situations: Fresh install or portable-mode switch where the storage value was never written; settings storage (INI or registry) deleted or reset; hand-edited settings file with the key removed.
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
- Missing RegistryKey value
- Invalid RegistryKey value
- Unsupported RegistryKey value
- throw ResultException(failure)
- throw PortableSettingsException(error)
AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12).
Data as JSON: /api/errors/8749e7e6c1139443.
Report an issue: GitHub.
Appendix: source
Thrown at src/windhawk/app/storage_manager.cpp:23
namespace {
// REG_NOTIFY_THREAD_AGNOSTIC keeps the notification alive after the thread that
// registered it exits, and lets it be re-armed from another thread.
constexpr DWORD kRegNotifyChangeKeyValueFlags =
REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_THREAD_AGNOSTIC;
std::filesystem::path PathFromStorage(
const PortableSettings& storage,
PCWSTR valueName,
const std::filesystem::path& baseFolderPath,
bool optional = false) {
auto storedPath = storage.GetString(valueName).value_or(L"");
if (storedPath.empty()) {
if (optional) {
return {};
}
throw std::runtime_error("Missing path value: " + CStringA(valueName));
}
#ifndef _WIN64
BOOL isWow64;
if (IsWow64Process(GetCurrentProcess(), &isWow64) && isWow64) {
// Get the native Program Files path regardless of the current
// process architecture.
storedPath =
Functions::ReplaceAll(storedPath, L"%ProgramFiles%",
L"%ProgramW6432%", /*ignoreCase=*/true);
}
#endif // _WIN64
auto expandedPath =
wil::ExpandEnvironmentStrings<std::wstring>(storedPath.c_str());
return (baseFolderPath / expandedPath).lexically_normal();
}
View on GitHub (pinned to 61d99ed8e1)