alibaba/spring-ai-alibaba · warning

实验 {} 状态为 {},无法停止

Error message

实验 {} 状态为 {},无法停止

What it means

ExperimentServiceImpl.stop refuses to stop an experiment that is already in a terminal state — COMPLETED, FAILED, or STOPPED. It logs this warning (including the ID and current status) and returns the unchanged experiment instead of throwing. Stopping is only meaningful for experiments still running or pending, since terminal states cannot transition to STOPPED.

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:279

        log.info("停止实验: {}", id);
        
        if (id == null) {
            throw new IllegalArgumentException("Experiment ID cannot be null");
        }
        
        // 获取实验信息
        ExperimentDO experimentDO = experimentMapper.selectById(id);
        if (experimentDO == null) {
            throw new IllegalArgumentException("Experiment not found: " + id);
        }



        // 检查实验状态
        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);
    }

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Check experiment status before calling stop; only issue stop when status is RUNNING/PENDING.
  2. Treat the returned experiment's terminal status as success (idempotent handling) rather than an error.
  3. Debounce/disable the stop button in the UI once the status poller reports a terminal state.
  4. If a stale status caused this, refresh the experiment via getById and re-evaluate.

Example fix

// before
Experiment exp = experimentService.getById(id);
experimentService.stop(id); // warning: already terminal

// after
Experiment exp = experimentService.getById(id);
if (!ExperimentStatus.COMPLETED.getCode().equals(exp.getStatus())
        && !ExperimentStatus.FAILED.getCode().equals(exp.getStatus())
        && !ExperimentStatus.STOPPED.getCode().equals(exp.getStatus())) {
    experimentService.stop(id);
}
Defensive patterns

Strategy: validation

Validate before calling

Set<String> terminal = Set.of(
    ExperimentStatus.COMPLETED.getCode(),
    ExperimentStatus.FAILED.getCode(),
    ExperimentStatus.STOPPED.getCode());
Experiment exp = experimentService.getById(id);
if (exp != null && terminal.contains(exp.getStatus())) {
    return; // already terminal, nothing to stop
}
experimentService.stop(id);

Try / catch

Experiment result = experimentService.stop(id);
if (terminalStatuses.contains(result.getStatus())) {
    log.info("Experiment {} already terminal ({}), stop was a no-op", id, result.getStatus());
}

Prevention

When it happens

Trigger: Calling experimentService.stop(id) on an experiment whose status is COMPLETED, FAILED, or STOPPED — e.g., a double-click on the stop button, or a client caching state and issuing a redundant stop after the experiment finished.

Common situations: Race between UI polling and user pressing stop; retry logic replaying a stop request after the experiment already failed/completed; scheduled job attempting cleanup of already-finished experiments.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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