theonedev/onedev · error · UnauthorizedException

Not authorized to create project under

Error message

Not authorized to create project under '${parent.path}'

What it means

checkProjectCreationPermission throws UnauthorizedException 'Not authorized to create project under <path>' when a parent is supplied but the subject lacks canCreateChildren on that parent. Both createProject and updateProject (on parent change) route through this check.

Solutions

  1. Grant the account permission to create child projects under the parent (project manage/owner or appropriate role)
  2. Create the project under a parent the account is allowed to use
  3. Use null parent with root-project creation rights if a root project suffices
Defensive patterns

Strategy: validation

Validate before calling

// before creating under a parent, confirm child-creation rights
if (parentId != null) {
  const parent = await api.get(`/rest/projects/${parentId}`);
  if (!userCanCreateChildren(currentUser, parent)) {
    throw new Error('not allowed to create children under ' + parent.path);
  }
}

Try / catch

try {
  await api.post('/rest/projects', payload);
} catch (e) {
  if (e.status === 401 && /create project under/.test(e.message)) {
    // request child-creation grant or choose another parent
  } else throw e;
}

Prevention

When it happens

Trigger: POST /rest/projects with parent set, or POST /rest/projects/{id} changing data.parentId, where the user cannot create child projects under the specified parent project.

Common situations: Non-member or guest trying to create a subproject in a team area; automation account whose child-creation permission was scoped away; group permission changes after setup.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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

Appendix: source

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

		if (!Objects.equals(oldParentId, Project.idOf(parent)))
			checkProjectCreationPermission(subject, parent);

		if (parent != null && project.isSelfOrAncestorOf(parent))
			throw new ExplicitException("Cannot use current or descendant project as parent");

		checkProjectNameDuplication(project);

		projectService.update(project);
		auditService.audit(project, "changed project via RESTful API", oldAuditContent,
				VersionedXmlDoc.fromBean(ProjectData.from(project)).toXML());

		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")

View on GitHub (pinned to d44925c47c)