theonedev/onedev · error · BadRequestException

Iteration is not defined in project hierarchy of the issue

Error message

Iteration is not defined in project hierarchy of the issue

What it means

During issue creation, each iterationId in the request is validated to belong to the issue's project or one of its ancestors. If the iteration's project is not self-or-ancestor of the issue's project, a BadRequestException (HTTP 400) is thrown. This keeps schedules consistent with the project hierarchy.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/IssueResource.java:346

		var issueSetting = settingService.getIssueSetting();
		
		Issue issue = new Issue();
		issue.setTitle(data.getTitle());
		issue.setDescription(data.getDescription());
		issue.setConfidential(data.isConfidential());
		issue.setProject(project);
		issue.setSubmitDate(new Date());
		issue.setSubmitter(user);
		issue.setState(issueSetting.getInitialStateSpec().getName());
		if (data.getOwnEstimatedTime() != null)
			issue.setOwnEstimatedTime(data.getOwnEstimatedTime());

		if (data.getIterationIds() != null) {
			for (Long iterationId : data.getIterationIds()) {
				Iteration iteration = iterationService.load(iterationId);
				if (!iteration.getProject().isSelfOrAncestorOf(project))
					throw new BadRequestException("Iteration is not defined in project hierarchy of the issue");
				IssueSchedule schedule = new IssueSchedule();
				schedule.setIssue(issue);
				schedule.setIteration(iteration);
				issue.getSchedules().add(schedule);
			}
		}

		issue.setFieldValues(FieldUtils.getFieldValues(subject, project, data.fields));
		issueService.open(issue);

		return issue.getId();
    }
	
	@Api(order=1100)
	@Path("/{issueId}/title")
    @POST
    public Response setTitle(@PathParam("issueId") Long issueId, @NotEmpty String title) {
		Issue issue = issueService.load(issueId);

View on GitHub (pinned to d44925c47c)

Solutions

  1. Use iteration ids that belong to the issue's project or one of its ancestors.
  2. Look up valid iterations via the iteration API filtered by the target project before posting.
  3. Remove iterationIds from the request if scheduling is unnecessary.

Example fix

// before
POST /api/issues {"title":"t","iterationIds":[99]}  // 99 belongs to another project
// after
POST /api/issues {"title":"t","iterationIds":[12]}   // 12 is an iteration of the issue's project or ancestor
Defensive patterns

Strategy: validation

Validate before calling

const validIterations = (await getIterations()).filter(it =>
  it.project.path === projectPath || projectAncestors(projectPath).includes(it.project.path));
const bad = body.iterationIds?.filter(id => !validIterations.some(it => it.id === id));
if (bad?.length) throw new Error(`Iterations not in project hierarchy: ${bad.join(',')}`);

Prevention

When it happens

Trigger: POST to /api/issues with iterationIds containing the id of an iteration defined in an unrelated project (sibling, child, or another hierarchy) rather than the issue's project or an ancestor.

Common situations: Hard-coded iteration ids from another project in automation scripts; copying iteration ids between projects; iterating over all project iterations instead of filtering by hierarchy.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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