theonedev/onedev · error · ExplicitException

Error invoking getter for 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.

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.

Appendix: 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)