{"record":{"id":"af0cf644ea346a50","repo":"theonedev/onedev","slug":"pull-request-merge-preview-not-calculated-yet","errorCode":null,"errorMessage":"Pull request merge preview not calculated yet","messagePattern":"Pull request merge preview not calculated yet","errorType":"http","errorClass":"ValidationException","httpStatus":400,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/JobRunResource.java","lineNumber":100,"sourceCode":"\t\t\tcommitId = ObjectId.fromString(jobRunOnCommit.getCommitHash());\n\t\t\t\n\t\t\tif (!gitService.isMergedInto(project, null, commitId, refCommit)) \n\t\t\t\tthrow new ValidationException(\"Specified commit is not reachable from specified ref\");\n\t\t\t\n\t\t\trefName = jobRunOnCommit.getRefName();\n\t\t\trequest = null;\n\t\t} else {\n\t\t\tJobRunOnPullRequest jobRunOnPullRequest = (JobRunOnPullRequest) jobRun;\n\t\t\trequest = pullRequestService.load(jobRunOnPullRequest.getPullRequestId());\n\t\t\trefName = request.getMergeRef();\n\t\t\tproject = request.getProject();\n\t\t\t\n\t\t\tif (!SecurityUtils.canRunJob(subject, request.getProject(), jobRun.getJobName()))\t\t\n\t\t\t\tthrow new UnauthorizedException();\n\n\t\t\tMergePreview preview = request.checkMergePreview();\n\t\t\tif (preview == null)\n\t\t\t\tthrow new ValidationException(\"Pull request merge preview not calculated yet\");\n\t\t\tif (preview.getMergeCommitHash() == null)\n\t\t\t\tthrow new ValidationException(\"Pull request has merge conflicts\");\n\t\t\t\n\t\t\tcommitId = ObjectId.fromString(preview.getMergeCommitHash());\n\t\t}\n\t\t\n\t\tBuild build = jobService.submit(user, project, commitId, jobRun.getJobName(), \n\t\t\t\tjobRun.getParams(), refName, request, null, jobRun.getReason());\n\t\tif (build.isFinished())\n\t\t\tjobService.resubmit(user, build, jobRun.getReason());\n\t\treturn build.getId();\n    }\n\n\t@Api(order=200)\n    @Path(\"/rebuild\")\n    @POST\n    public Response rebuild(@NotNull @Valid JobRerun jobRerun) {\n    \tBuild  build = buildService.load(jobRerun.buildId);","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/JobRunResource.java#L82-L118","documentation":"When running a job on a pull request, runBuild calls request.checkMergePreview(). If the merge preview has not been computed yet by the background merge-preview calculation, it returns null and the endpoint throws a ValidationException (HTTP 400). OneDev cannot determine which merge commit to build against.","triggerScenarios":"Submitting a job run on a pull request immediately after the PR was created or freshly updated, before OneDev finished calculating the merge preview.","commonSituations":"API automation racing PR creation; server under load delaying merge preview calculation; calling right after a push that invalidated the previous preview.","solutions":["Wait/retry until the pull request shows a calculated merge preview in the UI, then resubmit","Trigger a merge preview recalculation (open/refresh the PR) and retry after a short delay","Add retry-with-backoff around the API call in automation scripts"],"exampleFix":"// before\nrunJobOnPullRequest(prId); // throws if preview not ready\n// after\nawait pollUntilPrMergePreviewReady(prId, timeout=60s);\nrunJobOnPullRequest(prId);","handlingStrategy":"retry","validationCode":"// poll PR merge preview before submitting\nwhile (getPullRequest(id).mergePreview == null && elapsed < timeout) sleep(backoff);","typeGuard":null,"tryCatchPattern":"try { runBuild(pr); } catch (WebApplicationException e) { if (msg contains 'not calculated yet') retryWithBackoff(); else throw e; }","preventionTips":["Delay job submission after PR creation/update until preview is shown","Use exponential backoff in automation","Avoid racing the server's background merge-preview calculation"],"tags":["rest","pull-request","merge-preview","race-condition"],"backgroundTag":"invalid-state-transition","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}