java-native-access/jna · error · X11Exception

Invalid type of property

Error message

Invalid type of <prop_name> property

What it means

After XGetWindowProperty returns, Window.getProperty checks that the returned type atom matches the requested type (comparing native atom values). If the property exists but holds a different type than requested (or either atom is null), it frees the returned buffer and throws "Invalid type of <prop_name> property".

Solutions

  1. Match the requested type to what the WM actually stores: run xprop -root <NAME> and read the TYPE line
  2. For window-id lists use XA_WINDOW/XA_ATOM as appropriate instead of XA_CARDINAL
  3. Handle the fallback path: if _NET_* typed read fails, try the _WIN_* equivalent with its own type
  4. Catch X11Exception and retry with the alternate type

Example fix

// before
long[] pids = root.getIntProperty(X11.XA_CARDINAL, "_NET_CLIENT_LIST");
// after
long[] ids;
try {
    ids = root.getIntProperty(X11.XA_WINDOW, "_NET_CLIENT_LIST"); // client list holds WINDOW ids, not CARDINAL
} catch (X11Exception e) {
    ids = new long[0];
}
Defensive patterns

Strategy: validation

Validate before calling

// verify stored type matches what you request
// xprop -root _NET_CLIENT_LIST  ->  TYPE = WINDOW, not CARDINAL

Type guard

boolean typeMatches(X11.Atom actual, X11.Atom expected) {
    return actual != null && expected != null
        && actual.toNative().equals(expected.toNative());
}

Try / catch

try {
    value = win.getIntProperty(X11.XA_CARDINAL, atom);
} catch (X11Exception e) {
    if (e.getMessage().startsWith("Invalid type")) {
        value = win.getIntProperty(X11.XA_WINDOW, atom); // retry with real type
    } else throw e;
}

Prevention

When it happens

Trigger: Requesting XA_CARDINAL for a property stored as XA_WINDOW or XA_ATOM (e.g. reading _NET_WM_PID variants or client-list with the wrong expected type); mixing EWMH and WinWM property types.

Common situations: Code copied between properties with different types (CARDINAL vs WINDOW vs STRING), window managers storing hints with nonstandard types, or passing a null/unresolved atom as xa_prop_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/3a109e7d722168df. Report an issue: GitHub.

Appendix: source

Thrown at contrib/x11/src/jnacontrib/x11/api/X.java:1043

                //the specified property does not exist for the specified window
                return null;
            }

            if( xa_ret_type == null ){
                //the specified property does not exist for the specified window
                return null;
            }

            if( xa_ret_type == null ){
                //the specified property does not exist for the specified window
                return null;
            }

            if (xa_ret_type == null || xa_prop_type == null ||
                    !xa_ret_type.toNative().equals(xa_prop_type.toNative())) {
                x11.XFree(ret_prop);
                String prop_name = x11.XGetAtomName(display.x11Display, xa_prop_name);
                throw new X11Exception("Invalid type of " + prop_name + " property");
            }

            int ret_format = ret_format_ref.getValue();
            long ret_nitems = ret_nitems_ref.getValue().longValue();

            // null terminate the result to make string handling easier
            int nbytes;
            if (ret_format == 32)
                nbytes = Native.LONG_SIZE;
            else if (ret_format == 16)
                nbytes = Native.LONG_SIZE / 2;
            else if (ret_format == 8)
                nbytes = 1;
            else if (ret_format == 0)
                nbytes = 0;
            else
                throw new X11Exception("Invalid return format");
            int length = Math.min((int) ret_nitems * nbytes, MAX_PROPERTY_VALUE_LEN);

View on GitHub (pinned to d036ad9781)