java-native-access/jna · error · IllegalArgumentException
Function <name> declared Structure[] at parameter <index> bu
Error message
Function <name> declared Structure[] at parameter <index> but array of <type> was passed
What it means
When a mapped function expects Structure.ByReference[] (an array of pointers to structures) but the caller passed an array whose component type is a by-value Structure subclass, JNA throws IllegalArgumentException because it cannot safely reinterpret by-value elements as by-reference.
Source
Thrown at src/com/sun/jna/Function.java:592
return Boolean.TRUE.equals(arg) ? INTEGER_TRUE : INTEGER_FALSE;
} else if (String[].class == argClass) {
return new StringArray((String[])arg, encoding);
} else if (WString[].class == argClass) {
return new StringArray((WString[])arg);
} else if (Pointer[].class == argClass) {
return new PointerArray((Pointer[])arg);
} else if (NativeMapped[].class.isAssignableFrom(argClass)) {
return new NativeMappedArray((NativeMapped[])arg);
} else if (Structure[].class.isAssignableFrom(argClass)) {
// If the signature is Structure[], disallow
// Structure.ByReference[] and Structure.ByReference elements
Structure[] ss = (Structure[])arg;
Class<?> type = argClass.getComponentType();
boolean byRef = Structure.ByReference.class.isAssignableFrom(type);
if (expectedType != null) {
if (!Structure.ByReference[].class.isAssignableFrom(expectedType)) {
if (byRef) {
throw new IllegalArgumentException("Function " + getName()
+ " declared Structure[] at parameter "
+ index + " but array of "
+ type + " was passed");
}
for (int i=0;i < ss.length;i++) {
if (ss[i] instanceof Structure.ByReference) {
throw new IllegalArgumentException("Function " + getName()
+ " declared Structure[] at parameter "
+ index + " but element " + i
+ " is of Structure.ByReference type");
}
}
}
}
if (byRef) {
Structure.autoWrite(ss);
Pointer[] pointers = new Pointer[ss.length + 1];
for (int i=0;i < ss.length;i++) {View on GitHub (pinned to d036ad9781)
Solutions
- Change the argument to a Structure.ByReference[] (construct elements as ByReference instances)
- Or change the mapping's expected parameter type to Structure[] if the native API takes the array by value
- Ensure consistent ByReference annotations across the interface and call sites
Example fix
// before
MyStruct[] arr = { new MyStruct() }; // by value
f(arr);
// after
MyStruct.ByReference[] arr = { new MyStruct.ByReference() };
f(arr); Defensive patterns
Strategy: type-guard
Validate before calling
if (expectedType != null && Structure.ByReference[].class.isAssignableFrom(expectedType)) {
for (Structure s : ss) {
if (!(s instanceof Structure.ByReference)) throw new IllegalStateException("need ByReference elements");
}
} Type guard
boolean isByRefArray(Structure[] ss) {
return ss.length == 0 || ss[0] instanceof Structure.ByReference;
} Prevention
- Match the array element class to the mapping (ByReference[] needs ByReference elements)
- Keep one canonical element class per struct binding and construct arrays only from it
When it happens
Trigger: Calling a native function whose Java mapping declares Structure.ByReference[] (or an expectedType that is ByReference[]) while passing Structure[] where elements are by-value structures (not ByReference).
Common situations: Refactoring a struct array parameter from by-value to by-reference without updating call sites; mixing Structure and Structure.ByReference subclasses in the same codebase.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Function <name> declared Structure[] at parameter <index> bu
- Structure array must have non-zero length
- The given priority value is invalid!
- must be set from byte[]
- Unrecognized calling convention: <convention>
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/9442647fd68311b0.
Report an issue: GitHub.