theonedev/onedev · error · IllegalArgumentException

Can only compare with common ancestor when different project

Error message

Can only compare with common ancestor when different projects are involved

What it means

RevisionComparePage enforces an invariant on its compare state: when the comparison is not against the merge base, the left and right sides must belong to the same project; conversely, merge-base comparison is the only mode allowed when projects differ. Violating this while parsing URL parameters throws IllegalArgumentException with this message.

Source

Thrown at server-core/src/main/java/io/onedev/server/web/page/project/compare/RevisionComparePage.java:246

		else if (defaultRevision != null) 
			state.rightSide = new ProjectAndRevision(getProject(), defaultRevision);
		else
			state.rightSide = new ProjectAndRevision(getProject(), null);
		
		if (state.rightSide.getRevision() != null)
			rightCommitId = state.rightSide.getCommit().copy();
		
		state.compareWithMergeBase = params.get(PARAM_COMPARE_WITH_MERGE_BASE).toBoolean(true);
		
		/*
		 * When compare across different projects, left revision and right revision might not 
		 * exist in same project and this cause many difficulties such as calculating changes, 
		 * recording comment revisions, or get permanent mark urls. So we add below constraint as
		 * merge base commit and right side revision are guaranteed to be both in right side 
		 * project  
		 */
		if (!state.compareWithMergeBase && !state.leftSide.getProject().equals(state.rightSide.getProject())) 
			throw new IllegalArgumentException(_T("Can only compare with common ancestor when different projects are involved"));
		
		state.pathFilter = params.get(PARAM_PATH_FILTER).toString();
		state.blameFile = params.get(PARAM_BLAME_FILE).toString();
		state.whitespaceOption = WhitespaceOption.ofName(
				params.get(PARAM_WHITESPACE_OPTION).toString(WhitespaceOption.IGNORE_TRAILING.name()));
		
		state.commitQuery = params.get(PARAM_COMMIT_QUERY).toString();
		
		state.commentId = params.get(PARAM_COMMENT).toOptionalLong();
		state.mark = Mark.fromString(params.get(PARAM_MARK).toString());
		
		state.tabPanel = TabPanel.of(params.get(PARAM_TAB).toString());
		
		requestModel = new LoadableDetachableModel<PullRequest>() {

			@Override
			protected PullRequest load() {
				if (state.leftSide.getBranch() != null && state.rightSide.getBranch() != null) {

View on GitHub (pinned to d44925c47c)

Solutions

  1. Add/enable the merge-base comparison parameter in the URL when comparing across projects.
  2. Or restrict the comparison to two revisions within the same project.
  3. If generated programmatically, use RevisionComparePage.paramsOf / CompareParams helpers instead of hand-building the URL so flags stay consistent.

Example fix

// before
String url = "/~compare?query=a@projectA...b@projectB"; // no merge-base flag
// after
String url = "/~compare?query=a@projectA...b@projectB&compareWithMergeBase=true";
Defensive patterns

Strategy: validation

Validate before calling

boolean sameProject = leftProject.equals(rightProject);
boolean mergeBase = params.containsKey("compareWithMergeBase") && params.getBoolean("compareWithMergeBase");
if (!sameProject && !mergeBase) throw new IllegalArgumentException("Cross-project compare requires merge-base mode");

Try / catch

try {
    // open compare page
} catch (IllegalArgumentException e) {
    // rebuild URL with compareWithMergeBase=true
}

Prevention

When it happens

Trigger: Building a compare URL (PARAM_COMPARE_WITH_MERGE_BASE absent/false) where the left-side and right-side revisions resolve to different projects, e.g. manually crafted cross-project compare links without the merge-base flag.

Common situations: Constructing cross-project comparison URLs by hand or via scripts; bookmarks saved before a compare-layout change; copying a same-project compare link and swapping only the project of one side.

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/b6f9c7f2e114aa2c. Report an issue: GitHub.