ramensoftware/windhawk · error · std::runtime_error
Missing path value
Error message
Missing path value
What it means
PathFromStorage resolves a configured Windhawk storage path (e.g. the mods or compile artifacts folder) from PortableSettings, combining it with a base folder. If the setting value is missing or empty it throws runtime_error('Missing path value') because StorageManager cannot function without its folder locations.
Solutions
- Restore or recreate the Windhawk settings file so the expected path keys are present (reinstalling/repairing Windhawk regenerates defaults).
- Re-add the missing path setting to your portable settings/config file.
- If the file was hand-edited, revert to a backup that includes the path entries.
- Check for a failed upgrade/migration that dropped settings and rerun setup.
Example fix
// before (portable settings file) [Storage] ; ModsPath missing // after [Storage] ModsPath=D:\Windhawk\Mods
Defensive patterns
Strategy: try-catch
Validate before calling
// before constructing StorageManager, confirm required keys exist
for (PCWSTR key : {L"ModsPath", L"CompiledModsPath" /* etc */}) {
if (settings.GetString(key).value_or(L"").empty()) {
LOG(L"Storage setting '%s' is missing", key);
RestoreDefaultSettings();
}
} Try / catch
try {
StorageManager::GetInstance();
} catch (const std::runtime_error& e) {
if (std::string_view(e.what()) == "Missing path value") {
LOG(L"Storage settings incomplete; regenerating defaults");
ResetStorageSettingsToDefaults();
}
} Prevention
- Back up the Windhawk settings file before manual edits or upgrades.
- After updates, verify all storage path keys are present in the settings store.
- Keep portable settings files complete when copying between machines.
- Catch this during first-run setup and write defaults instead of crashing.
When it happens
Trigger: StorageManager construction reading a storage key (via PathFromStorage) that has no value in the settings store — e.g. a fresh/corrupted Windhawk settings file missing the expected path entries.
Common situations: First run with an incomplete settings file; settings store wiped or partially migrated after an update; manual edits deleting a path key; portable-config files copied without the path entries.
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 path value
- Missing LibraryFileName value
- Missing RegistryKey value
- Invalid RegistryKey value
- Unsupported RegistryKey value
AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12).
Data as JSON: /api/errors/f5cad50a0786998c.
Report an issue: GitHub.
Appendix: source
Thrown at src/windhawk/engine/storage_manager.cpp:24
extern HINSTANCE g_hDllInst;
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. The main
// loop relies on this: it hops between threads.
constexpr DWORD kRegNotifyChangeKeyValueFlags = REG_NOTIFY_CHANGE_NAME |
REG_NOTIFY_CHANGE_LAST_SET |
REG_NOTIFY_THREAD_AGNOSTIC;
std::filesystem::path PathFromStorage(
const PortableSettings& storage,
PCWSTR valueName,
const std::filesystem::path& baseFolderPath) {
auto storedPath = storage.GetString(valueName).value_or(L"");
if (storedPath.empty()) {
throw std::runtime_error("Missing path value");
}
#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());
// Some processes, e.g. csrss.exe, have a limited amount of environment
// variables set. Specifically, we need %ProgramData%, so if it's missing,View on GitHub (pinned to 61d99ed8e1)