{"record":{"id":"79b230d2259c57e2","repo":"theonedev/onedev","slug":"error-invoking-getter-for-property-dependson-pr","errorCode":null,"errorMessage":"Error invoking getter for property: ${dependsOn.property()}","messagePattern":"Error invoking getter for property: (.+?)","errorType":"validation","errorClass":"ExplicitException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java","lineNumber":1362,"sourceCode":"\t\t\t\treturn false; // Skip validation for constraints from overridden superclass methods\n\t\t\t}\n\t\t\tvar bean = valueContext.getCurrentBean();\t\t\t\n\t\t\tvar propertyName = ((AbstractPropertyConstraintLocation<?>) location).getPropertyName();\n\t\t\tvar getter = BeanUtils.findGetter(bean.getClass(), propertyName);\n\t\t\tif (getter == null) {\n\t\t\t\tthrow new ExplicitException(\"Getter not found for property: \" + propertyName);\n\t\t\t}\n\t\t\tfor (var dependsOn : getter.getAnnotationsByType(DependsOn.class)) {\n\t\t\t\tvar dependencyGetter = BeanUtils.findGetter(bean.getClass(), dependsOn.property());\n\t\t\t\tif (dependencyGetter == null) {\n\t\t\t\t\tthrow new ExplicitException(\"Getter not found for property: \" + dependsOn.property());\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tvar dependencyPropertyValue = dependencyGetter.invoke(bean);\n\t\t\t\t\tif (!DependsOnUtils.isPropertyVisible(dependsOn, dependencyGetter.getReturnType(), dependencyPropertyValue))\n\t\t\t\t\t\treturn false;\n\t\t\t\t} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {\n\t\t\t\t\tthrow new ExplicitException(\"Error invoking getter for property: \" + dependsOn.property(), e);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar showCondition = getter.getAnnotation(ShowCondition.class);\n\t\t\tif (showCondition != null) {\n\t\t\t\tEditContext.push(new EditContext() {\n\t\t\t\t\t@Override\n\t\t\t\t\tpublic Object getInputValue(String name) {\n\t\t\t\t\t\tvar getter =  BeanUtils.findGetter(bean.getClass(), name);\n\t\t\t\t\t\tif (getter == null) {\n\t\t\t\t\t\t\tfor (var eachGetter: BeanUtils.findGetters(bean.getClass())) {\n\t\t\t\t\t\t\t\tif (EditableUtils.getDisplayName(eachGetter).equals(name)) {\n\t\t\t\t\t\t\t\t\tgetter = eachGetter;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (getter == null) \n\t\t\t\t\t\t\t\tthrow new ExplicitException(\"Getter not found for property: \" + name);\n\t\t\t\t\t\t}","sourceCodeStart":1344,"sourceCodeEnd":1380,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java#L1344-L1380","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Inspect the wrapped cause (ExplicitException carries the original exception) and fix the exception thrown inside the getter.","Make the getter defensive: return a safe default instead of throwing when state is incomplete.","Ensure the getter has no side effects and works on partially initialized beans.","Check accessor visibility/accessibility (make it public if reached across packages)."],"exampleFix":"// before\npublic String getRepoName() {\n    return project.getName(); // NPE when project is null\n}\n\n// after\npublic String getRepoName() {\n    return project != null ? project.getName() : null;\n}","handlingStrategy":"try-catch","validationCode":"Object val = null;\ntry { val = dependencyGetter.invoke(bean); }\ncatch (Exception e) { throw new IllegalStateException(\n    \"getter \" + dependencyGetter + \" not safe to invoke\", e); }","typeGuard":"static <T> T safeInvoke(ThrowingSupplier<T> getter, T fallback) {\n    try { return getter.get(); } catch (Throwable t) { return fallback; }\n}","tryCatchPattern":"try {\n    validator.validate(bean);\n} catch (Exception e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Error invoking getter\")) {\n        Throwable cause = e.getCause(); // fix the real failure inside the getter\n    } else throw e;\n}","preventionTips":["Keep getters side-effect-free and null-safe on partially initialized beans.","Log and inspect e.getCause() — the reflective exception wraps the real bug.","Cover every @DependsOn getter with a test that invokes it on a default-constructed bean."],"tags":["validation","reflection","onedev","getter-invocation"],"backgroundTag":"getter-not-found","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}