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
- Match the requested type to what the WM actually stores: run xprop -root <NAME> and read the TYPE line
- For window-id lists use XA_WINDOW/XA_ATOM as appropriate instead of XA_CARDINAL
- Handle the fallback path: if _NET_* typed read fails, try the _WIN_* equivalent with its own type
- 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
- Check each property's stored TYPE with xprop before coding against it
- Don't assume CARDINAL for all hints; window lists use WINDOW/ATOM types
- Try _NET_* and _WIN_* variants with their own declared types
- Keep a small atom->type map for the properties you use
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
- Cannot get property.
- Attempting to retrieve VisualID from a null Visual
- Callback type must be an interface
- Can't open X Display
- Can't open X Display
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)