alibaba/spring-ai-alibaba · warning
未找到ID为{}的实验
Error message
未找到ID为{}的实验 What it means
ExperimentServiceImpl.getById logs this warning when experimentMapper.selectById(id) returns null, meaning no experiment row exists for the given ID. The method then returns null; it does not throw. Callers that skip the null check will hit a NullPointerException when using the returned Experiment.
Source
Thrown at spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/service/impl/ExperimentServiceImpl.java:142
(long) request.getPageNumber(),
(long) request.getPageSize(),
experimentDOList.stream()
.map(Experiment::fromDO)
.toList());
}
@Override
public Experiment getById(Long id) {
log.info("查询实验详情: {}", id);
if (id == null) {
throw new IllegalArgumentException("Experiment ID cannot be null");
}
ExperimentDO experimentDO = experimentMapper.selectById(id);
if (experimentDO == null) {
log.warn("未找到ID为{}的实验", id);
return null;
}
Experiment experiment = Experiment.fromDO(experimentDO);
List<EvaluatorConfig> evaluatorConfigList = JSON.parseArray(experiment.getEvaluatorConfig(), EvaluatorConfig.class);
evaluatorConfigList.stream()
.filter(Objects::nonNull)
.forEach(evaluatorConfig -> {
try {
EvaluatorDO evaluatorDO = evaluatorMapper.selectById(evaluatorConfig.getEvaluatorId());
evaluatorConfig.setEvaluatorName(evaluatorDO != null ? evaluatorDO.getName() : "Unknown Evaluator");
} catch (Exception e) {
log.warn("Failed to fetch evaluator name for id: {}", evaluatorConfig.getEvaluatorId(), e);
evaluatorConfig.setEvaluatorName("Error Fetching Name");
}
});View on GitHub (pinned to f82da0b50f)
Solutions
- Check experiment existence (experimentMapper.selectById or a COUNT query) before calling getById.
- Null-check the return value and map it to a NOT_FOUND response.
- Confirm the application is connected to the intended database/environment.
- Re-create the experiment if it was deleted, or refresh the ID from a fresh list() call.
Example fix
// before
Experiment exp = experimentService.getById(id);
Long versionId = exp.getDatasetVersionId(); // NPE if not found
// after
Experiment exp = experimentService.getById(id);
if (exp == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Experiment not found: " + id);
} Defensive patterns
Strategy: type-guard
Validate before calling
public static boolean experimentExists(Long id) {
return id != null && experimentMapper.selectById(id) != null;
} Type guard
Experiment exp = experimentService.getById(id);
if (exp == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Experiment not found: " + id);
} Prevention
- Null-check results from experimentService.getById before dereferencing.
- Refresh experiment IDs from list() rather than caching them across sessions.
- Confirm the datasource points at the expected environment.
- Handle deletion races: re-fetch on 404 in UI flows.
When it happens
Trigger: Calling experimentService.getById(id) with an ID absent from the experiment table, e.g., a deleted experiment or an ID from another environment/database.
Common situations: UI retains a link to a removed experiment; concurrent deletion between listing and detail fetch; tests use arbitrary IDs without seeding; wrong datasource pointing at an empty schema.
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
- 实验不存在: {}
- Dataset version not found: {}
- Invalid experiment status: {}
- Failed to fetch evaluator name for id: {}
- 实验 {} 状态为 {},无法停止
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/41695c5b5012c6c3.
Report an issue: GitHub.