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
- Add/enable the merge-base comparison parameter in the URL when comparing across projects.
- Or restrict the comparison to two revisions within the same project.
- 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
- Use paramsOf/CompareParams helpers to build compare URLs.
- Always enable merge-base comparison for cross-project compares.
- Validate left/right project equality before generating links.
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
- No default branch in project:
- Ref not found (project:
- Project not specified
- Project not found or inaccessible: <projectPath>
- Authentication required
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/b6f9c7f2e114aa2c.
Report an issue: GitHub.