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

  1. Validate with new CFTypeRef(value).isTypeID(CoreFoundation.STRING_TYPE_ID) before calling setValue.
  2. Create CFStrings explicitly via CFStringRef.createCFString(javaString) when you intend to store a string.
  3. Pass null if the slot should be cleared — null skips the type check.
  4. 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

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


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)