{"record":{"id":"5a14e2c0349ba187","repo":"theonedev/onedev","slug":"violation-propertypath-violation-message","errorCode":null,"errorMessage":"${violation.propertyPath}: ${violation.message}","messagePattern":"\\$\\{violation\\.propertyPath\\}: \\$\\{violation\\.message\\}","errorType":"http","errorClass":"ExplicitException","httpStatus":500,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java","lineNumber":384,"sourceCode":"\t\t\tif (parent != null) {\n\t\t\t\tthrow new ExplicitException(\"Name '\" + project.getName() + \"' is already used by another project under '\"\n\t\t\t\t\t\t+ parent.getPath() + \"'\");\n\t\t\t} else {\n\t\t\t\tthrow new ExplicitException(\"Name '\" + project.getName() + \"' is already used by another root project\");\n\t\t\t}\n\t\t}\n\t}\n\t\n\t@Api(order=900, description=\"Update project settings\")\n\t@Path(\"/{projectId}/setting\")\n    @POST\n    public Response updateSetting(@PathParam(\"projectId\") Long projectId, @NotNull ProjectSetting setting) {\n\t\tfor (var boardSpec: setting.getIssueSetting().getBoardSpecs())\n\t\t\tboardSpec.populateEditColumns();\n\t\tvar violations = validator.validate(setting);\n\t\tif (!violations.isEmpty()) {\n\t\t\tvar violation = violations.iterator().next();\n\t\t\tthrow new ExplicitException(violation.getPropertyPath() + \": \" + violation.getMessage());\n\t\t}\n\n    \tProject project = projectService.load(projectId);\n    \tif (!SecurityUtils.canManageProject(project)) \n\t\t\tthrow new UnauthorizedException();\n\t\tvar oldAuditContent = VersionedXmlDoc.fromBean(ProjectSetting.from(project)).toXML();\n\t\tsetting.populate(project);\n\t\tprojectService.update(project);\n\t\tauditService.audit(project, \"changed project settings via RESTful API\", oldAuditContent, VersionedXmlDoc.fromBean(setting).toXML());\n\t\t\n\t\treturn Response.ok().build();\n    }\n\t\n\t@Api(order=1000)\n\t@Path(\"/{projectId}\")\n    @DELETE\n    public Response deleteProject(@PathParam(\"projectId\") Long projectId) {\n    \tProject project = projectService.load(projectId);","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java#L366-L402","documentation":"ProjectResource.updateSetting validates the submitted ProjectSetting bean with the Jakarta Bean Validation validator. The first constraint violation is rethrown as ExplicitException formatted as '<propertyPath>: <message>'. It reports that some field of the project settings payload fails its declared validation constraints.","triggerScenarios":"POST to /{projectId}/setting with a ProjectSetting body where any nested bean property violates a @NotNull/@Size/etc. constraint — e.g. empty issue setting fields, invalid board specs, missing required strings.","commonSituations":"Automation scripts posting partial settings objects that omit required fields; hand-crafted JSON missing mandatory properties; API version changes adding new required constraints on issue settings or board specs.","solutions":["Read the propertyPath in the message to locate the offending field and fix its value in the payload.","Send a complete ProjectSetting: fetch current settings first and modify only needed fields.","Ensure each board spec has valid edit columns (the endpoint calls populateEditColumns before validation)."],"exampleFix":"// before\nPOST /{projectId}/setting {\"issueSetting\": {\"boardSpecs\": [{\"name\": \"\"}]}}\n// -> 'boardSpecs[0].name: size must be between 1 and 100'\n// after\nPOST /{projectId}/setting {\"issueSetting\": {\"boardSpecs\": [{\"name\": \"My Board\", \"editColumns\": [...]}]}}","handlingStrategy":"validation","validationCode":"// Validate settings client-side before POST\nSet<ConstraintViolation<ProjectSetting>> violations = validator.validate(setting);\nif (!violations.isEmpty()) {\n    ConstraintViolation<ProjectSetting> v = violations.iterator().next();\n    throw new IllegalArgumentException(v.getPropertyPath() + \": \" + v.getMessage());\n}","typeGuard":null,"tryCatchPattern":"try { updateSetting(projectId, setting); } catch (ExplicitException e) { log.error(\"Invalid setting: {}\", e.getMessage()); }","preventionTips":["Load current settings via API and patch fields instead of building payloads from scratch","Keep board spec names and edit columns non-empty and within size limits","Re-run validation after OneDev upgrades that may add constraints"],"tags":["rest-api","bean-validation","settings"],"backgroundTag":"schema-validation-failed","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"}