theonedev/onedev · error · ExplicitException

${violation.propertyPath}: ${violation.message}

Error message

${violation.propertyPath}: ${violation.message}

What it means

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.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java:384

			if (parent != null) {
				throw new ExplicitException("Name '" + project.getName() + "' is already used by another project under '"
						+ parent.getPath() + "'");
			} else {
				throw new ExplicitException("Name '" + project.getName() + "' is already used by another root project");
			}
		}
	}
	
	@Api(order=900, description="Update project settings")
	@Path("/{projectId}/setting")
    @POST
    public Response updateSetting(@PathParam("projectId") Long projectId, @NotNull ProjectSetting setting) {
		for (var boardSpec: setting.getIssueSetting().getBoardSpecs())
			boardSpec.populateEditColumns();
		var violations = validator.validate(setting);
		if (!violations.isEmpty()) {
			var violation = violations.iterator().next();
			throw new ExplicitException(violation.getPropertyPath() + ": " + violation.getMessage());
		}

    	Project project = projectService.load(projectId);
    	if (!SecurityUtils.canManageProject(project)) 
			throw new UnauthorizedException();
		var oldAuditContent = VersionedXmlDoc.fromBean(ProjectSetting.from(project)).toXML();
		setting.populate(project);
		projectService.update(project);
		auditService.audit(project, "changed project settings via RESTful API", oldAuditContent, VersionedXmlDoc.fromBean(setting).toXML());
		
		return Response.ok().build();
    }
	
	@Api(order=1000)
	@Path("/{projectId}")
    @DELETE
    public Response deleteProject(@PathParam("projectId") Long projectId) {
    	Project project = projectService.load(projectId);

View on GitHub (pinned to d44925c47c)

Solutions

  1. Read the propertyPath in the message to locate the offending field and fix its value in the payload.
  2. Send a complete ProjectSetting: fetch current settings first and modify only needed fields.
  3. Ensure each board spec has valid edit columns (the endpoint calls populateEditColumns before validation).

Example fix

// before
POST /{projectId}/setting {"issueSetting": {"boardSpecs": [{"name": ""}]}}
// -> 'boardSpecs[0].name: size must be between 1 and 100'
// after
POST /{projectId}/setting {"issueSetting": {"boardSpecs": [{"name": "My Board", "editColumns": [...]}]}}
Defensive patterns

Strategy: validation

Validate before calling

// Validate settings client-side before POST
Set<ConstraintViolation<ProjectSetting>> violations = validator.validate(setting);
if (!violations.isEmpty()) {
    ConstraintViolation<ProjectSetting> v = violations.iterator().next();
    throw new IllegalArgumentException(v.getPropertyPath() + ": " + v.getMessage());
}

Try / catch

try { updateSetting(projectId, setting); } catch (ExplicitException e) { log.error("Invalid setting: {}", e.getMessage()); }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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