theonedev/onedev · error · ExplicitException

Error invoking getter for property: ${dependsOn.property()}

Error message

Error invoking getter for property: ${dependsOn.property()}

What it means

OneDev wraps reflective invocation failures of a @DependsOn-referenced getter into an ExplicitException: when dependencyGetter.invoke(bean) throws IllegalAccessException, IllegalArgumentException, or InvocationTargetException while evaluating the dependency property's value for visibility checks, this error surfaces with the underlying cause attached.

Source

Thrown at server-core/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java:1362

				return false; // Skip validation for constraints from overridden superclass methods
			}
			var bean = valueContext.getCurrentBean();			
			var propertyName = ((AbstractPropertyConstraintLocation<?>) location).getPropertyName();
			var getter = BeanUtils.findGetter(bean.getClass(), propertyName);
			if (getter == null) {
				throw new ExplicitException("Getter not found for property: " + propertyName);
			}
			for (var dependsOn : getter.getAnnotationsByType(DependsOn.class)) {
				var dependencyGetter = BeanUtils.findGetter(bean.getClass(), dependsOn.property());
				if (dependencyGetter == null) {
					throw new ExplicitException("Getter not found for property: " + dependsOn.property());
				}
				try {
					var dependencyPropertyValue = dependencyGetter.invoke(bean);
					if (!DependsOnUtils.isPropertyVisible(dependsOn, dependencyGetter.getReturnType(), dependencyPropertyValue))
						return false;
				} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
					throw new ExplicitException("Error invoking getter for property: " + dependsOn.property(), e);
				}
			}
			var showCondition = getter.getAnnotation(ShowCondition.class);
			if (showCondition != null) {
				EditContext.push(new EditContext() {
					@Override
					public Object getInputValue(String name) {
						var getter =  BeanUtils.findGetter(bean.getClass(), name);
						if (getter == null) {
							for (var eachGetter: BeanUtils.findGetters(bean.getClass())) {
								if (EditableUtils.getDisplayName(eachGetter).equals(name)) {
									getter = eachGetter;
									break;
								}
							}
							if (getter == null) 
								throw new ExplicitException("Getter not found for property: " + name);
						}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Inspect the wrapped cause (ExplicitException carries the original exception) and fix the exception thrown inside the getter.
  2. Make the getter defensive: return a safe default instead of throwing when state is incomplete.
  3. Ensure the getter has no side effects and works on partially initialized beans.
  4. Check accessor visibility/accessibility (make it public if reached across packages).

Example fix

// before
public String getRepoName() {
    return project.getName(); // NPE when project is null
}

// after
public String getRepoName() {
    return project != null ? project.getName() : null;
}
Defensive patterns

Strategy: try-catch

Validate before calling

Object val = null;
try { val = dependencyGetter.invoke(bean); }
catch (Exception e) { throw new IllegalStateException(
    "getter " + dependencyGetter + " not safe to invoke", e); }

Type guard

static <T> T safeInvoke(ThrowingSupplier<T> getter, T fallback) {
    try { return getter.get(); } catch (Throwable t) { return fallback; }
}

Try / catch

try {
    validator.validate(bean);
} catch (Exception e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Error invoking getter")) {
        Throwable cause = e.getCause(); // fix the real failure inside the getter
    } else throw e;
}

Prevention

When it happens

Trigger: A @DependsOn-referenced getter throws a runtime exception during validation (e.g. NPE dereferencing an uninitialized field), is inaccessible (private getter on a class reached reflectively without access), or is invoked with a mismatched receiver (bean of wrong class).

Common situations: Getters with side-effecting logic that fail on partially constructed beans, getters depending on external state (config not loaded yet), security-manager or module access restrictions, or getters that throw for legacy/incompatible stored values.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/79b230d2259c57e2. Report an issue: GitHub.