alibaba/spring-ai-alibaba · error · RuntimeException
Failed to stop experiment
Error message
Failed to stop experiment
What it means
Thrown by ExperimentServiceImpl.stop when the MyBatis-Plus updateById call returns 0 rows affected, meaning the experiment row could not be updated to STOPPED status. The library treats any non-positive update result as a hard failure and wraps it in a RuntimeException.
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:291
// 检查实验状态
if (ExperimentStatus.COMPLETED.getCode().equals(experimentDO.getStatus()) ||
ExperimentStatus.FAILED.getCode().equals(experimentDO.getStatus()) ||
ExperimentStatus.STOPPED.getCode().equals(experimentDO.getStatus())) {
log.warn("实验 {} 状态为 {},无法停止", id, experimentDO.getStatus());
return Experiment.fromDO(experimentDO);
}
// 更新实验状态为已停止
experimentDO.setStatus(String.valueOf(ExperimentStatus.STOPPED));
experimentDO.setUpdateTime(LocalDateTime.now());
int result = experimentMapper.updateById(experimentDO);
if (result <= 0) {
throw new RuntimeException("Failed to stop experiment");
}
log.info("实验停止成功: {}", id);
return Experiment.fromDO(experimentDO);
}
@Override
@Transactional
public void deleteById(Long id) {
log.info("删除实验: {}", id);
if (id == null) {
throw new IllegalArgumentException("Experiment ID cannot be null");
}
// 检查实验是否存在
ExperimentDO experimentDO = experimentMapper.selectById(id);
if (experimentDO == null) {View on GitHub (pinned to f82da0b50f)
Solutions
- Verify the experiment id exists (experimentMapper.selectById) before calling stop
- Re-check whether the experiment was already stopped or deleted and make the stop operation idempotent
- Check database connectivity/permissions and logs for the underlying SQL failure
- Catch RuntimeException in the controller and return a 404/409 with a clear message
Example fix
// before
experimentDO.setStatus(String.valueOf(ExperimentStatus.STOPPED));
int result = experimentMapper.updateById(experimentDO);
if (result <= 0) {
throw new RuntimeException("Failed to stop experiment");
}
// after
ExperimentDO existing = experimentMapper.selectById(id);
if (existing == null) {
throw new IllegalArgumentException("Experiment not found: " + id);
}
existing.setStatus(String.valueOf(ExperimentStatus.STOPPED));
existing.setUpdateTime(LocalDateTime.now());
int result = experimentMapper.updateById(existing);
if (result <= 0) {
throw new IllegalStateException("Failed to stop experiment: " + id);
} Defensive patterns
Strategy: try-catch
Validate before calling
ExperimentDO exp = experimentMapper.selectById(id);
if (exp == null) throw new IllegalArgumentException("not found: " + id);
if (ExperimentStatus.STOPPED.getCode().equals(exp.getStatus())) return; // already stopped Type guard
boolean existsAndStoppable(Long id) { ExperimentDO e = experimentMapper.selectById(id); return e != null && !ExperimentStatus.STOPPED.getCode().equals(e.getStatus()); } Try / catch
try { experimentService.stop(id); } catch (RuntimeException e) { log.warn("stop failed for {}", id, e); /* check existence, rethrow 404/409 */ } Prevention
- Check the experiment exists before stopping
- Make stop idempotent for already-stopped experiments
- Monitor DB connectivity in the admin server
When it happens
Trigger: Calling stop(id) for an experiment whose row no longer exists (deleted concurrently), an id pointing to a non-existent record, or a database write failure/constraint that prevents the update.
Common situations: Race condition where the experiment is deleted by another request/thread while stop is in flight; wrong id passed from the client; database connectivity or permission issues in the admin server environment.
Related errors
- 数据项删除失败:
- Failed to create dataset version
- Failed to delete experiment
- Failed to fetch evaluator name for id: {}
- INVALID_PARAMS
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/26fa9ced399c795b.
Report an issue: GitHub.