java-native-access/jna · error · ClassCastException

Unable to cast to CFDictionary. Type ID

Error message

Unable to cast to CFDictionary. Type ID: {getTypeID()}

What it means

CFDictionaryRef's Pointer constructor validates that the wrapped Core Foundation object is a CFDictionary by comparing its CFTypeID against DICTIONARY_TYPE_ID, throwing ClassCastException if it is not. This prevents narrowing arbitrary CFTypeRefs into dictionary references.

Solutions

  1. Guard with new CFTypeRef(p).isTypeID(CoreFoundation.DICTIONARY_TYPE_ID) before constructing.
  2. Null-check the pointer before the cast.
  3. For polymorphic values, inspect getTypeID() and dispatch per type (string/number/array/dictionary).
  4. Fix the key/lookup path if a nested dictionary was expected but a scalar was returned.

Example fix

// before
CFDictionaryRef dict = new CFDictionaryRef(value); // throws
// after
CFTypeRef ref = new CFTypeRef(value);
if (ref.isTypeID(CoreFoundation.DICTIONARY_TYPE_ID)) {
    CFDictionaryRef dict = new CFDictionaryRef(value);
} else {
    // handle non-dictionary value
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (value != null && new CFTypeRef(value).isTypeID(CoreFoundation.DICTIONARY_TYPE_ID)) {
    CFDictionaryRef dict = new CFDictionaryRef(value);
}

Type guard

boolean isCFDictionary(Pointer p) {
    return p != null && new CFTypeRef(p).isTypeID(CoreFoundation.DICTIONARY_TYPE_ID);
}

Try / catch

try {
    CFDictionaryRef dict = new CFDictionaryRef(value);
} catch (ClassCastException e) {
    // nested value was a scalar/array, not a dictionary
}

Prevention

When it happens

Trigger: Constructing new CFDictionaryRef(pointer) from a generic CFTypeRef result — e.g. a CFArray element, CFNumber, CFString, or a NULL pointer — where CFGetTypeID does not report the dictionary type id.

Common situations: Fetching a value from a parent dictionary that turns out to be a string or array, not a nested dictionary; missing keys returning NULL; iterating collections whose element types vary.

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/90825fd870b00082. Report an issue: GitHub.

Appendix: source

Thrown at contrib/platform/src/com/sun/jna/platform/mac/CoreFoundation.java:422

            public CoreFoundation.CFDictionaryRef getDictionaryRefValue() {
                Pointer value = super.getValue();
                if (value == null) {
                    return null;
                }

                return new CoreFoundation.CFDictionaryRef(value);
            }
        }

        public CFDictionaryRef() {
            super();
        }

        public CFDictionaryRef(Pointer p) {
            super(p);
            if (!isTypeID(DICTIONARY_TYPE_ID)) {
                throw new ClassCastException("Unable to cast to CFDictionary. Type ID: " + getTypeID());
            }
        }

        /**
         * Convenience method for {@link CoreFoundation#CFDictionaryGetValue} on this
         * object.
         *
         * @param key
         *            The key for which to find a match.
         * @return The value associated with key, or {@code null} if no key-value pair
         *         matching key exists.
         */
        public Pointer getValue(PointerType key) {
            return INSTANCE.CFDictionaryGetValue(this, key);
        }

        /**
         * Convenience method for {@link CoreFoundation#CFDictionaryGetCount(CFDictionaryRef)}

View on GitHub (pinned to d036ad9781)