{"record":{"id":"a9528fefe358ecbf","repo":"java-native-access/jna","slug":"unexpected-registry-type-lptype-getvalue-expected-reg-sz","errorCode":null,"errorMessage":"Unexpected registry type + lpType.getValue() + , expected REG_SZ","messagePattern":"Unexpected registry type \\+ lpType\\.getValue\\(\\) \\+ , expected REG_SZ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java","lineNumber":863,"sourceCode":"     * Get a registry REG_EXPAND_SZ value.\n     *\n     * @param hKey\n     *            Parent Key.\n     * @param value\n     *            Name of the value to retrieve.\n     * @return String value.\n     */\n    public static String registryGetExpandableStringValue(HKEY hKey, String value) {\n        IntByReference lpcbData = new IntByReference();\n        IntByReference lpType = new IntByReference();\n        int rc = Advapi32.INSTANCE.RegQueryValueEx(hKey, value, 0,\n                lpType, (char[]) null, lpcbData);\n        if (rc != W32Errors.ERROR_SUCCESS\n                && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {\n            throw new Win32Exception(rc);\n        }\n        if (lpType.getValue() != WinNT.REG_EXPAND_SZ) {\n            throw new RuntimeException(\"Unexpected registry type \"\n                    + lpType.getValue() + \", expected REG_SZ\");\n        }\n        if (lpcbData.getValue() == 0) {\n            return \"\";\n        }\n        // See comment in #registryGetValue\n        Memory mem = new Memory(lpcbData.getValue() + Native.WCHAR_SIZE);\n        mem.clear();\n        rc = Advapi32.INSTANCE.RegQueryValueEx(hKey, value, 0,\n            lpType, mem, lpcbData);\n        if (rc != W32Errors.ERROR_SUCCESS\n                && rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {\n            throw new Win32Exception(rc);\n        }\n        if (W32APITypeMapper.DEFAULT == W32APITypeMapper.UNICODE) {\n            return mem.getWideString(0);\n        } else {\n            return mem.getString(0);","sourceCodeStart":845,"sourceCodeEnd":881,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java#L845-L881","documentation":"Advapi32Util.registryGetExpandableStringValue first queries the registry value with RegQueryValueEx using a NULL buffer to learn the value's type via lpType. If the returned type is not WinNT.REG_EXPAND_SZ, the library throws this RuntimeException because the retrieved data would not be an expandable string. The message text itself is slightly misleading (says REG_SZ), but the check is against REG_EXPAND_SZ. It is a defensive guard so callers never receive wrongly-decoded data.","triggerScenarios":"Calling Advapi32Util.registryGetExpandableStringValue(root, key, value) (or the samDesiredExtra overload) where the named registry value exists but has a type other than REG_EXPAND_SZ, e.g. it is REG_SZ, REG_DWORD or REG_BINARY.","commonSituations":"Reading a value that an installer or another application rewrote as a plain REG_SZ; guessing that a value is expandable when it was created with setValue returning REG_SZ; hardcoding value names from documentation that changed between Windows versions.","solutions":["Open regedit or use Advapi32Util.registryGetValue / registryQueryInfoKey to check the value's actual type before reading.","Call registryGetStringValue instead if the value is REG_SZ, or the matching getter for its actual type.","Use registryGetValue, which dispatches on the reported type and returns an Object, when the type is not known in advance.","Catch RuntimeException around the typed getter and fall back to a generic read."],"exampleFix":"// before\nString v = Advapi32Util.registryGetExpandableStringValue(WinReg.HKEY_LOCAL_MACHINE, \"SOFTWARE\\\\MyApp\", \"Path\");\n\n// after\nObject raw = Advapi32Util.registryGetValue(WinReg.HKEY_LOCAL_MACHINE, \"SOFTWARE\\\\MyApp\", \"Path\");\nString v = raw instanceof String ? (String) raw : String.valueOf(raw);","handlingStrategy":"validation","validationCode":"// check the value's type before the typed read\nAdvapi32Util.InfoKey info = Advapi32Util.registryQueryInfoKey(key, 0);\n// or cheaper: read generically and instanceof-check\nObject v = Advapi32Util.registryGetValue(root, keyPath, valueName);\nif (!(v instanceof String)) throw new IllegalStateException(\"Expected expandable string\");","typeGuard":"boolean isExpandableString(Object v) { return v instanceof String; }","tryCatchPattern":"try { return Advapi32Util.registryGetExpandableStringValue(root, key, value); }\ncatch (RuntimeException e) { log.warn(\"Not REG_EXPAND_SZ: {}\", value); return null; }","preventionTips":["Query the value type with registryQueryInfoKey before using a typed getter","Prefer registryGetValue when the type is not guaranteed","Never assume a value's type from its name or documentation alone","Re-check types after installers or group policy may rewrite values"],"tags":["windows-registry","type-mismatch","jna","reg-expand-sz"],"backgroundTag":"type-mismatch","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}