spring-projects/spring-framework · error · InvalidPropertyException

Invalid property '{propertyName}' of bean class [{beanClass.

Error message

Invalid property '{propertyName}' of bean class [{beanClass.getName()}]: Illegal attempt to get property '{actualName}' threw exception

What it means

Thrown as an InvalidPropertyException when reading a property via a BeanWrapper/property accessor and the getter invocation throws an exception that is NOT already handled by a more specific catch (InvocationTargetException, NumberFormatException, TypeMismatchException, IndexOutOfBoundsException). It is the generic fallback in getPropertyValue(PropertyTokenHolder) at AbstractNestablePropertyAccessor.java:698-701, wrapping the original cause. The message literally accuses an 'Illegal attempt to get property'.

Source

Thrown at spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java:699

			return value;
		}
		catch (InvalidPropertyException ex) {
			throw ex;
		}
		catch (IndexOutOfBoundsException ex) {
			throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
					"Index of out of bounds in property path '" + propertyName + "'", ex);
		}
		catch (NumberFormatException | TypeMismatchException ex) {
			throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
					"Invalid index in property path '" + propertyName + "'", ex);
		}
		catch (InvocationTargetException ex) {
			throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
					"Getter for property '" + actualName + "' threw exception", ex);
		}
		catch (Exception ex) {
			throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
					"Illegal attempt to get property '" + actualName + "' threw exception", ex);
		}
	}


	/**
	 * Return the {@link PropertyHandler} for the specified {@code propertyName}, navigating
	 * if necessary. Return {@code null} if not found rather than throwing an exception.
	 * @param propertyName the property to obtain the descriptor for
	 * @return the property descriptor for the specified property,
	 * or {@code null} if not found
	 * @throws BeansException in case of introspection failure
	 */
	protected @Nullable PropertyHandler getPropertyHandler(String propertyName) throws BeansException {
		Assert.notNull(propertyName, "Property name must not be null");
		AbstractNestablePropertyAccessor nestedPa = getPropertyAccessorForPropertyPath(propertyName);
		return nestedPa.getLocalPropertyHandler(getFinalPath(nestedPa, propertyName));
	}

View on GitHub (pinned to 69bf83ad71)

Solutions

  1. Inspect the wrapped cause via getCause()/getRootCause() of the InvalidPropertyException to find the real exception thrown by the getter.
  2. Reproduce by calling the bean's getter directly (bean.getXyz()) outside of the BeanWrapper to confirm the getter itself throws.
  3. Fix the getter to not throw, or guard the upstream state so the property is read only when valid.
  4. If reading through a proxy, ensure the target bean's method is public and the proxy/AOP advice is not failing.

Example fix

// before: derived getter throws when inner list is null
public int getCount() { return items.size(); }

// after: null-safe getter
public int getCount() { return items != null ? items.size() : 0; }
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the getter is safe before traversal
PropertyHandler check via reflection:
PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(bean.getClass(), "x");
if (pd != null && pd.getReadMethod() != null
        && wrapper.isReadableProperty("x")) {
    // safe-ish; still call inside try/catch
}

Type guard

// Narrow to beans whose getter does not throw by sampling
static boolean safeToRead(BeanWrapper w, String path) {
    try { w.getPropertyValue(path); return true; }
    catch (InvalidPropertyException ex) {
        return !(ex.getCause() instanceof RuntimeException);
    }
}

Try / catch

try {
    Object v = wrapper.getPropertyValue(nestedPath);
} catch (InvalidPropertyException ex) {
    Throwable root = ex.getCause(); // the real exception from the getter
    // distinguish getter-failure (root != null) from genuine invalid path
    log.warn("getter for {} threw", nestedPath, root);
}

Prevention

When it happens

Trigger: Call getPropertyValue on a nested/indexed path whose underlying PropertyHandler.getValue() (the read method or field accessor) throws a RuntimeException such as IllegalStateException, IllegalArgumentException from inside the getter, an AOP/proxy failure, a NullPointerException surfaced from the getter body, or a privileged-action exception that is not an InvocationTargetException.

Common situations: Data binding onto a bean whose getter computes/derives a value and that computation fails (e.g. getSubtotal() divides by zero or dereferences a null); a CGLIB/proxied bean whose advice throws in the getter; SpEL/BeanWrapper property traversal where an intermediate getter relies on uninitialized state; reading a property on a Kotlin/record type whose accessor has side effects.

Related errors


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/05176b20c3e4fb1a. Report an issue: GitHub.