theonedev/onedev · error · ExplicitException

Name '${project.name}' is already used by another root proje

Error message

Name '${project.name}' is already used by another root project

What it means

Variant of the duplicate-name check for root-level projects: when a project has no parent, its name must be unique among all root projects. checkProjectNameDuplication throws ExplicitException when another root project already uses the name.

Source

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

		return Response.ok().build();
	}
	
	private void checkProjectCreationPermission(Subject subject, @Nullable Project parent) {
		if (parent != null && !SecurityUtils.canCreateChildren(subject, parent))
			throw new UnauthorizedException("Not authorized to create project under '" + parent.getPath() + "'");
		if (parent == null && !SecurityUtils.canCreateRootProjects(subject))
			throw new UnauthorizedException("Not authorized to create root project");
	}
	
	private void checkProjectNameDuplication(Project project) {
		Project parent = project.getParent();
		Project projectWithSameName = projectService.find(parent, project.getName());
		if (projectWithSameName != null && !projectWithSameName.equals(project)) {
			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)) 

View on GitHub (pinned to d44925c47c)

Solutions

  1. Use a unique root-level project name (or nest it under a parent where the name is available).
  2. Rename or remove the conflicting existing root project.
  3. If the goal is to modify the existing root project, issue an update against its projectId instead.

Example fix

// before
POST /api/projects {"name": "infra"}  // root project 'infra' already exists
// after
POST /api/projects {"name": "infra", "parentPath": "platform"}
// or unique name
POST /api/projects {"name": "infra-prod"}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure root-level name uniqueness before create
if (project.getParent() == null && projectService.find(null, project.getName()) != null) {
    throw new IllegalStateException("Root project '" + project.getName() + "' already exists");
}

Try / catch

try { projectService.create(...); } catch (ExplicitException e) { log.warn("Duplicate root project name: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Creating or renaming a project with no parent (parent == null) via the REST API when a root project with the same name already exists.

Common situations: CI/automation creating top-level projects with generic names like 'build' or 'test' that already exist; importing projects that were previously nested but are now created at root level.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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