{"record":{"id":"be2038e6bb62d7a2","repo":"java-native-access/jna","slug":"getunknownid-formatmessagefromhr","errorCode":null,"errorMessage":"getUnknownId: <formatMessageFromHR>","messagePattern":"getUnknownId: <formatMessageFromHR>","errorType":"exception","errorClass":"com.sun.jna.platform.win32.COM.COMException","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java","lineNumber":120,"sourceCode":"            try {\n                final PointerByReference ppvObject = new PointerByReference();\n\n                Thread current = Thread.currentThread();\n                String tn = current.getName();\n\n                IID iid = com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN;\n                HRESULT hr = ProxyObject.this.getRawDispatch().QueryInterface(new REFIID(iid), ppvObject);\n\n                if (WinNT.S_OK.equals(hr)) {\n                    Dispatch dispatch = new Dispatch(ppvObject.getValue());\n                    this.unknownId = Pointer.nativeValue(dispatch.getPointer());\n                    // QueryInterface returns a COM object pointer with a +1\n                    // reference, we must drop one,\n                    // Note: createProxy adds one;\n                    int n = dispatch.Release();\n                } else {\n                    String formatMessageFromHR = Kernel32Util.formatMessage(hr);\n                    throw new COMException(\"getUnknownId: \" + formatMessageFromHR, hr);\n                }\n            } catch (RuntimeException e) {\n                // Do not rewrap COMException\n                if (e instanceof COMException) {\n                    throw e;\n                } else {\n                    throw new COMException(\"Error occured when trying get Unknown Id \", e);\n                }\n            }\n        }\n        return this.unknownId;\n    }\n\n    @Override\n    protected void finalize() throws Throwable {\n        this.dispose();\n        super.finalize();\n    }","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java#L102-L138","documentation":"This COMException is thrown by ProxyObject.getUnknownId() when the underlying COM call to obtain the IUnknown identifier fails with a non-zero HRESULT. The library appends the human-readable Windows error message (via Kernel32Util.formatMessage) to help identify the exact COM failure. It signals that the proxy could not retrieve or negotiate the IUnknown pointer for the wrapped COM object.","triggerScenarios":"The raw dispatch.QueryInterface(IUnknown) or related COM call returns a failed HRESULT; the COM object has been released from another thread (RCW released) or its apartment (STA/MTA) requirements are violated.","commonSituations":"Calling proxy methods from a thread that is not the COM apartment owner; the underlying COM server crashed or released the object; cross-apartment marshaling without proper initialization (CoInitialize missing).","solutions":["Ensure COM is initialized on the calling thread (COMUtils.comIsInitialized) and use the object from the thread/apartment that created it","Wrap calls in the handler utilities provided (com.sun.jna.platform.win32.COM.util.HandlerUtil) which marshal calls to the creating thread","Catch COMException and inspect getHresult() to identify the specific Windows error code","Release and re-create the proxy if the underlying COM object was freed"],"exampleFix":"// before\nObject id = proxy.getUnknownId(); // throws if called off-apartment\n// after\nif (COMUtils.comIsInitialized()) {\n    Object id = HandlerUtil.getObjectIdentity(handler); // marshals to owner thread\n}","handlingStrategy":"try-catch","validationCode":"if (!COMUtils.comIsInitialized()) { throw new IllegalStateException(\"COM not initialized on this thread\"); }","typeGuard":"boolean usable = proxy != null && COMUtils.comIsInitialized();","tryCatchPattern":"try { Object id = proxy.getUnknownId(); } catch (COMException e) { LOG.error(\"getUnknownId failed hr=0x\" + Integer.toHexString(e.getHresult().intValue()), e); }","preventionTips":["Initialize COM per-thread with ComFactory/COMUtils before touching proxies","Keep proxy usage on the thread that created it or use HandlerUtil marshaling","Do not release the underlying dispatch while the proxy is alive"],"tags":["com","windows","jni","hresult"],"backgroundTag":"internal-invariant-violation","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"}