SonarSource/sonarqube · error · NotFoundException
Analysis ' ' not found
Error message
Analysis '%s' not found
What it means
api/project_analyses/delete cannot find the requested analysis (snapshot) by uuid, or the snapshot exists but has UNPROCESSED status, which is treated as not-found. DeleteAction.selects the snapshot by uuid and throws analysisNotFoundException('Analysis %s not found') in both cases.
Solutions
- Re-fetch the analysis uuid via api/project_analyses/search?project=<key> and use a current uuid.
- Wait until the analysis finishes processing (status becomes PROCESSED) before deleting.
- Make the deletion idempotent: treat 404 as success in cleanup scripts.
- Verify you are calling the right SonarQube instance/environment where the analysis exists.
Example fix
// before
deleteAnalysis('AXh3kQ9exampleUuid'); // already deleted
// after
const analyses = await get(`/api/project_analyses/search?project=${key}`);
for (const a of analyses.analyses) {
if (a.status === 'PROCESSED' && !a.last) await deleteAnalysis(a.key);
} Defensive patterns
Strategy: try-catch
Validate before calling
// always resolve a fresh uuid before deleting
const search = await get(`/api/project_analyses/search?project=${encodeURIComponent(key)}`);
const target = search.analyses.find(a => a.key === analysisUuid);
if (!target) throw new Error(`Analysis ${analysisUuid} no longer exists`);
if (target.status !== 'PROCESSED') throw new Error('Analysis still processing; retry later');
if (target.last) throw new Error('Refusing to delete the last analysis'); Type guard
function isDeletableAnalysis(a) {
return Boolean(a) && a.status === 'PROCESSED' && a.last === false;
} Try / catch
try {
await deleteAnalysis(uuid);
} catch (e) {
if (isNotFound(e, /Analysis .* not found/)) {
log.info(`Analysis ${uuid} already gone; treating as deleted`);
return;
}
throw e;
} Prevention
- Make retention scripts idempotent: 404 means already deleted.
- Never reuse uuids from old logs; re-list analyses each run.
- Skip UNPROCESSED snapshots and the most recent analysis.
When it happens
Trigger: DELETE api/project_analyses/delete with a PARAM_ANALYSIS uuid that does not exist, was already deleted, or refers to an analysis still in UNPROCESSED (in-progress) status.
Common situations: Retention scripts replaying a delete for an already-deleted analysis; hardcoded uuid copied from an old log; calling delete while an analysis is still being processed on the compute engine.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Issue with key ' ' does not exist
- Metrics are not found
- Plugin not found
- Project ' ' not found
- The following metric keys are not found
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/bd4c83f7ca19c1e6.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/DeleteAction.java:74
.setSince("6.3")
.setPost(true)
.setHandler(this);
action.createParam(PARAM_ANALYSIS)
.setDescription("Analysis key")
.setExampleValue(Uuids.UUID_EXAMPLE_04)
.setRequired(true);
}
@Override
public void handle(Request request, Response response) throws Exception {
String analysisUuid = request.mandatoryParam(PARAM_ANALYSIS);
try (DbSession dbSession = dbClient.openSession(false)) {
SnapshotDto analysis = dbClient.snapshotDao().selectByUuid(dbSession, analysisUuid)
.orElseThrow(() -> analysisNotFoundException(analysisUuid));
if (STATUS_UNPROCESSED.equals(analysis.getStatus())) {
throw analysisNotFoundException(analysisUuid);
}
userSession.checkComponentUuidPermission(ProjectPermission.ADMIN, analysis.getRootComponentUuid());
checkArgument(!analysis.getLast(), "The last analysis '%s' cannot be deleted", analysisUuid);
checkNotUsedInNewCodePeriod(dbSession, analysis);
analysis.setStatus(STATUS_UNPROCESSED);
dbClient.snapshotDao().update(dbSession, analysis);
dbSession.commit();
}
response.noContent();
}
private void checkNotUsedInNewCodePeriod(DbSession dbSession, SnapshotDto analysis) {
boolean isSetAsBaseline = dbClient.newCodePeriodDao().existsByProjectAnalysisUuid(dbSession, analysis.getUuid());
checkArgument(!isSetAsBaseline,
"The analysis '%s' can not be deleted because it is set as a new code period baseline", analysis.getUuid());
View on GitHub (pinned to 184c821202)