java-native-access/jna · error · ClassCastException
Unable to cast to CFString. Type ID
Error message
Unable to cast to CFString. Type ID: {typeId} What it means
CFStringRef.ByReference.setValue checks that the Pointer assigned is a CFString by comparing CFGetTypeID against STRING_TYPE_ID and throws ClassCastException if it is not (null is permitted and bypasses the check). It guards dictionary/string-typed out-parameters against receiving other CFTypes.
Solutions
- Validate with new CFTypeRef(value).isTypeID(CoreFoundation.STRING_TYPE_ID) before calling setValue.
- Create CFStrings explicitly via CFStringRef.createCFString(javaString) when you intend to store a string.
- Pass null if the slot should be cleared — null skips the type check.
- Inspect the reported type id in the exception to identify what object was mistakenly passed.
Example fix
// before
stringRef.setValue(somePointer); // throws if not a CFString
// after
CFStringRef str = CFStringRef.createCFString("value");
stringRef.setValue(str); Defensive patterns
Strategy: type-guard
Validate before calling
if (value == null || new CFTypeRef(value).isTypeID(CoreFoundation.STRING_TYPE_ID)) {
stringRef.setValue(value);
} Type guard
boolean isCFString(Pointer p) {
return p != null && new CFTypeRef(p).isTypeID(CoreFoundation.STRING_TYPE_ID);
} Try / catch
try {
stringRef.setValue(value);
} catch (ClassCastException e) {
// non-string assigned; create a CFString explicitly instead
} Prevention
- Build CFStrings with CFStringRef.createCFString rather than wrapping raw pointers
- Verify STRING_TYPE_ID before assigning pointers to ByReference slots
- Pass null to clear slots instead of zeroed/garbage pointers
- Separate raw CFTypeRef plumbing from typed CFStringRef usage
When it happens
Trigger: Calling setValue(pointer) on a CFStringRef.ByReference with a pointer to a CFNumber, CFArray, CFBoolean, CFData, or any non-string CFType.
Common situations: Assigning results from generic CF functions that return multiple possible types; passing the wrong variable or wrong ByReference slot; populating struct fields where the producer wrote a non-string type.
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 CFArray. Type ID
- 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
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/03b136a657032cea.
Report an issue: GitHub.
Appendix: source
Thrown at contrib/platform/src/com/sun/jna/platform/mac/CoreFoundation.java:516
/**
* Placeholder for a reference to a {@code CFString} object.
*/
public static class ByReference extends PointerByReference {
public ByReference() {
this(null);
}
public ByReference(CoreFoundation.CFStringRef value) {
super(value != null ? value.getPointer() : null);
}
@Override
public void setValue(Pointer value) {
if (value != null) {
CFTypeID typeId = INSTANCE.CFGetTypeID(value);
if (!STRING_TYPE_ID.equals(typeId)) {
throw new ClassCastException("Unable to cast to CFString. Type ID: " + typeId);
}
}
super.setValue(value);
}
public CoreFoundation.CFStringRef getStringRefValue() {
Pointer value = super.getValue();
if (value == null) {
return null;
}
return new CoreFoundation.CFStringRef(value);
}
}
public CFStringRef() {
super();View on GitHub (pinned to d036ad9781)