{"record":{"id":"ea219cf3f4fe9666","repo":"java-native-access/jna","slug":"can-t-autogenerate-a-direct-buffer-on-memory-read","errorCode":null,"errorMessage":"Can't autogenerate a direct buffer on memory read","messagePattern":"Can't autogenerate a direct buffer on memory read","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/com/sun/jna/Pointer.java","lineNumber":428,"sourceCode":"            if (fp == null) {\n                result = null;\n            } else {\n                Callback cb = (Callback)currentValue;\n                Pointer oldfp = CallbackReference.getFunctionPointer(cb);\n                if (!fp.equals(oldfp)) {\n                    cb = CallbackReference.getCallback(type, fp);\n                }\n                result = cb;\n            }\n        } else if (Platform.HAS_BUFFERS && Buffer.class.isAssignableFrom(type)) {\n            Pointer bp = getPointer(offset);\n            if (bp == null) {\n                result = null;\n            } else {\n                Pointer oldbp = currentValue == null ? null\n                    : Native.getDirectBufferPointer((Buffer)currentValue);\n                if (oldbp == null || !oldbp.equals(bp)) {\n                    throw new IllegalStateException(\"Can't autogenerate a direct buffer on memory read\");\n                }\n                result = currentValue;\n            }\n        } else if (NativeMapped.class.isAssignableFrom(type)) {\n            NativeMapped nm = (NativeMapped)currentValue;\n            if (nm != null) {\n                Object value = getValue(offset, nm.nativeType(), null);\n                result = nm.fromNative(value, new FromNativeContext(type));\n                if (nm.equals(result)) {\n                    result = nm;\n                }\n            } else {\n                NativeMappedConverter tc = NativeMappedConverter.getInstance(type);\n                Object value = getValue(offset, tc.nativeType(), null);\n                result = tc.fromNative(value, new FromNativeContext(type));\n            }\n        } else if (type.isArray()) {\n            result = currentValue;","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Pointer.java#L410-L446","documentation":"Pointer.getValue throws IllegalStateException when reading a Buffer-typed value from memory: JNA cannot materialize a new direct ByteBuffer for the read; it only returns an existing initialized direct Buffer whose backing native pointer matches the memory being read. Autogenerating a buffer during a read is not allowed.","triggerScenarios":"Calling Pointer.getValue(offset, Buffer.class, currentValue) where currentValue is null or a Buffer whose Native.getDirectBufferPointer does not equal the pointer at this offset.","commonSituations":"Reading a Structure field typed as Buffer that was never initialized with a direct ByteBuffer; passing a heap (non-direct) buffer like ByteBuffer.allocate instead of allocateDirect; buffer's native pointer changed after reallocation.","solutions":["Initialize the field with a direct ByteBuffer: ByteBuffer.allocateDirect(n) before reading","Use Pointer.getByteBuffer(offset, size) explicitly instead of getValue with Buffer.class","Ensure the same direct buffer instance is reused and not reallocated between calls","Use Pointer/byte[] types in structures if readback of new memory is needed"],"exampleFix":"// before\nByteBuffer buf; // null or heap buffer\nPointer.getValue(offset, ByteBuffer.class, buf);\n// after\nByteBuffer buf = ByteBuffer.allocateDirect(64);\npointer.getValue(offset, ByteBuffer.class, buf); // returns same buffer","handlingStrategy":"validation","validationCode":"if (buf == null || !buf.isDirect()) {\n    buf = ByteBuffer.allocateDirect(size);\n}","typeGuard":"static boolean isDirectBuffer(Object o) {\n    return o instanceof Buffer && ((Buffer) o).isDirect();\n}","tryCatchPattern":null,"preventionTips":["Always pre-initialize Buffer-typed structure fields with direct buffers","Never reallocate a buffer whose pointer JNA has already captured","Use getByteBuffer(offset, size) for one-off reads"],"tags":["jna","pointer","direct-buffer","illegal-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}