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

  1. Restore the missing value in the settings storage (settings.ini or the registry key)
  2. Reinstall or run Windhawk's repair to repopulate default storage values
  3. If the path is genuinely optional, mark the optional parameter true at the call site
  4. 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

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


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)