On-prem Azure DevOps pull request analysis failure

We’re using SonarQube Developer Edition 8.2.0.32929 with a PostgreSQL 10.11 database. Our builds are running on AzureDevops Server 2019. So far, branch analysis works just fine for us and we have no issues.

Pull request analysis will consistently fail on some pull requests at the Publish Quality Gate stage. The error message is:
Visit failed for Component {key=Project_KEY:Project:PULL_REQUEST:6881,type=DIRECTORY} located Project_KEY:PULL_REQUEST:6881(type=PROJECT)

I’ve turned on debug logging on the sonar server and it didn’t produce anything more useful. For now, we’ve had to turn off pull request analysis, but we really like it when it works, so I would love to get it going again.

Any advice on how to debug this would be appreciated.

The full stack trace is below.

org.sonar.ce.task.projectanalysis.component.VisitException: Visit failed for Component {key=Project_KEY:Project:PULL_REQUEST:6881,type=DIRECTORY}  located Project_Key:PULL_REQUEST:6881(type=PROJECT)

	at org.sonar.ce.task.projectanalysis.component.VisitException.rethrowOrWrap(VisitException.java:44)
	at org.sonar.ce.task.projectanalysis.component.PathAwareCrawler.visit(PathAwareCrawler.java:52)
	at org.sonar.ce.task.projectanalysis.component.PathAwareCrawler.visitChildren(PathAwareCrawler.java:87)
	at org.sonar.ce.task.projectanalysis.component.PathAwareCrawler.visitImpl(PathAwareCrawler.java:70)
	at org.sonar.ce.task.projectanalysis.component.PathAwareCrawler.visit(PathAwareCrawler.java:50)
	at org.sonar.ce.task.projectanalysis.step.PersistComponentsStep.execute(PersistComponentsStep.java:114)
	at org.sonar.ce.task.step.ComputationStepExecutor.executeStep(ComputationStepExecutor.java:81)
	at org.sonar.ce.task.step.ComputationStepExecutor.executeSteps(ComputationStepExecutor.java:72)
	at org.sonar.ce.task.step.ComputationStepExecutor.execute(ComputationStepExecutor.java:59)
	at org.sonar.ce.task.projectanalysis.taskprocessor.ReportTaskProcessor.process(ReportTaskProcessor.java:81)
	at org.sonar.ce.taskprocessor.CeWorkerImpl$ExecuteTask.executeTask(CeWorkerImpl.java:209)
	at org.sonar.ce.taskprocessor.CeWorkerImpl$ExecuteTask.run(CeWorkerImpl.java:191)
	at org.sonar.ce.taskprocessor.CeWorkerImpl.findAndProcessTask(CeWorkerImpl.java:158)
	at org.sonar.ce.taskprocessor.CeWorkerImpl$TrackRunningState.get(CeWorkerImpl.java:133)
	at org.sonar.ce.taskprocessor.CeWorkerImpl.call(CeWorkerImpl.java:85)
	at org.sonar.ce.taskprocessor.CeWorkerImpl.call(CeWorkerImpl.java:53)
	at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:125)
	at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:69)
	at com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:78)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.IllegalArgumentException: Component name can't be empty
	at com.google.common.base.Preconditions.checkArgument(Preconditions.java:142)
	at org.sonar.db.component.ComponentValidator.checkComponentName(ComponentValidator.java:40)
	at org.sonar.db.component.ComponentDto.setName(ComponentDto.java:316)
	at org.sonar.ce.task.projectanalysis.step.PersistComponentsStep$PersistComponentStepsVisitor.createForDirectory(PersistComponentsStep.java:302)
	at org.sonar.ce.task.projectanalysis.step.PersistComponentsStep$PersistComponentStepsVisitor.visitDirectory(PersistComponentsStep.java:211)
	at org.sonar.ce.task.projectanalysis.component.PathAwareCrawler.visitNode(PathAwareCrawler.java:99)
	at org.sonar.ce.task.projectanalysis.component.PathAwareCrawler.visitImpl(PathAwareCrawler.java:67)
	at org.sonar.ce.task.projectanalysis.component.PathAwareCrawler.visit(PathAwareCrawler.java:50)
	... 23 more

Here is my current state: I was able to find a failing PR to do some testing. I broke the PR into as many change sets as I could and submitted them one by one. The analysis worked just fine until I changed a specific file.

It turned out that any change I made to this file - even a comment change - would cause analysis to fail. I then took that file, made a brand new pull request with just those changes, and analysis succeeded. So I’m stumped again.

Ok, so I decided to create a new SQ project to test with. I did a full analysis of the master branch, then did a PR analysis that was previously failing and it succeeded.

We did our first analysis in December, so the database isn’t very old. We did upgrade from Community Edition to Developer Edition using the same DB. Is it possible that corrupted things?

It looks like I’m going to have to blow away and recreate every project just to be safe.

Ok, I finally figured it out. I removed my SQ project and recreated one with the same name, and suddenly my PR analysis stopped working again. The issue is — the SQ project name.

Yes, if the name of the SonarQube project matches the name of a directory being analyzed, the PR analysis may fail. Technically, it will only fail if the directory name is a root of the analysis.

So, if I have a project named Project1 and I have directory in my repo called Project1, and I change files as follows:
Project1/Folder1/source1.cs
Project1/Folder2/source2.cs

The analysis will fail because the two files have a common root in Project1 and the analysis confuses the ‘directory’ Project1 with the SQ ‘project’ Project1.

But the following changes will not fail:
Project1/Folder1/source1.cs
Project1/Folder1/source2.cs

I believe this is because the root is now Project1/Folder1 and there is no confusion.

This is why my PR analysis failures seemed so random, and it actually kind of makes sense given the original error message.