java-native-access/jna · error · ClassCastException
Unable to cast to CFArray. Type ID
Error message
Unable to cast to CFArray. Type ID: {getTypeID()} What it means
CFArrayRef's Pointer constructor checks that the wrapped Core Foundation object's type id equals the CFArray type id and throws ClassCastException if not. This guards against narrowing an arbitrary CFTypeRef/Pointer into CFArrayRef.
Solutions
- Validate with new CFTypeRef(p).isTypeID(CoreFoundation.ARRAY_TYPE_ID) before constructing CFArrayRef.
- Check for NULL pointers before casting (missing key/element).
- Remember CFArray elements are CFTypeRefs — inspect each element's type id individually instead of assuming array-ness.
- Fix the lookup path if the producer stores a scalar where an array was expected.
Example fix
// before
CFArrayRef arr = new CFArrayRef(value); // throws if value is a CFString
// after
CFTypeRef ref = new CFTypeRef(value);
if (ref.isTypeID(CoreFoundation.ARRAY_TYPE_ID)) {
CFArrayRef arr = new CFArrayRef(value);
} else {
// treat as scalar value
} Defensive patterns
Strategy: type-guard
Validate before calling
if (value != null && new CFTypeRef(value).isTypeID(CoreFoundation.ARRAY_TYPE_ID)) {
CFArrayRef arr = new CFArrayRef(value);
} Type guard
boolean isCFArray(Pointer p) {
return p != null && new CFTypeRef(p).isTypeID(CoreFoundation.ARRAY_TYPE_ID);
} Try / catch
try {
CFArrayRef arr = new CFArrayRef(value);
} catch (ClassCastException e) {
// scalar value where array expected; handle by type
} Prevention
- Verify array-ness via isTypeID before constructing
- Inspect each CFArray element's type id individually — elements are CFTypeRefs
- Null-check results before casting
- Dispatch on CFGetTypeID when a value can legitimately be multiple types
When it happens
Trigger: Constructing new CFArrayRef(pointer) from a polymorphic result such as a value read from a CFDictionary (e.g. valueForKey returning a CFString) or a NULL pointer whose type id is 0.
Common situations: Reading a dictionary entry expected to be a list but actually a scalar; iterating heterogeneous CFArray elements and mis-casting an element (arrays store CFTypeRefs, not CFArrayRefs); released/invalid pointers.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Unable to cast to CFBoolean. Type ID
- Unable to cast to CFData. Type ID
- Unable to cast to CFDictionary. Type ID
- Unable to cast to CFDictionary. Type ID
- Unable to cast to CFNumber. Type ID
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/edf3b33604fdce72.
Report an issue: GitHub.
Appendix: source
Thrown at contrib/platform/src/com/sun/jna/platform/mac/CoreFoundation.java:316
}
}
/**
* A reference to an immutable {@code CFArray} object.
* <p>
* CFArray is “toll-free bridged” with its Cocoa Foundation counterpart,
* {@code NSArray}. Therefore, in a method where you see an {@code NSArray *}
* parameter, you can pass in a {@code CFArrayRef} .
*/
class CFArrayRef extends CFTypeRef {
public CFArrayRef() {
super();
}
public CFArrayRef(Pointer p) {
super(p);
if (!isTypeID(ARRAY_TYPE_ID)) {
throw new ClassCastException("Unable to cast to CFArray. Type ID: " + getTypeID());
}
}
/**
* Convenience method for {@link #CFArrayGetCount} on this object
*
* @return The number of values in this array.
*/
public int getCount() {
return INSTANCE.CFArrayGetCount(this).intValue();
}
/**
* Convenience method for {@link #CFArrayGetValueAtIndex} on this object
*
* @param idx
* The index of the value to retrieve.
* @return The value at the {@code idx} index.View on GitHub (pinned to d036ad9781)