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

  1. Check experiment existence (experimentMapper.selectById or a COUNT query) before calling getById.
  2. Null-check the return value and map it to a NOT_FOUND response.
  3. Confirm the application is connected to the intended database/environment.
  4. 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

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


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/41695c5b5012c6c3. Report an issue: GitHub.