java-native-access/jna · error · IllegalArgumentException
Function <name> declared Structure[] at parameter <index> bu
Error message
Function <name> declared Structure[] at parameter <index> but element <i> is of Structure.ByReference type
What it means
The inverse of error 326: if the mapping declares Structure[] by value, every element must NOT be a Structure.ByReference instance. A by-reference element in a by-value array is ambiguous for marshaling, so JNA rejects it at the specific offending index.
Source
Thrown at src/com/sun/jna/Function.java:599
} 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++) {
pointers[i] = ss[i] != null ? ss[i].getPointer() : null;
}
return new PointerArray(pointers);
} else if (ss.length == 0) {
throw new IllegalArgumentException("Structure array must have non-zero length");
} else if (ss[0] == null) {
Structure.newInstance((Class<? extends Structure>) type).toArray(ss);View on GitHub (pinned to d036ad9781)
Solutions
- Create all array elements as the by-value class (e.g. new MyStruct(), not new MyStruct.ByReference())
- If references are intended, change the mapping to Structure.ByReference[]
- Use Structure.newInstance(byValueClass).toArray(ss) to populate arrays with correct element types
Example fix
// before
MyStruct[] arr = { new MyStruct.ByReference() };
f(arr);
// after
MyStruct[] arr = { new MyStruct() };
f(arr); Defensive patterns
Strategy: type-guard
Validate before calling
for (int i = 0; i < ss.length; i++) {
if (ss[i] instanceof Structure.ByReference)
throw new IllegalStateException("by-value expected at element " + i);
} Type guard
boolean isByValueArray(Structure[] ss) {
for (Structure s : ss) if (s instanceof Structure.ByReference) return false;
return true;
} Prevention
- Never mix MyStruct and MyStruct.ByReference instances in one array
- Populate structure arrays via newInstance(byValueClass).toArray() to guarantee element type
When it happens
Trigger: Passing Structure[] where one or more elements were constructed as Structure.ByReference (directly or via newInstance of a ByReference subclass) while the function expects by-value structures.
Common situations: Mixing MyStruct and MyStruct.ByReference instances in one array after a refactor; auto-generated arrays that used ByReference for the element class.
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/bb04b9a7a1d501da.
Report an issue: GitHub.