sgl-project/sglang · error · ValueError

Unknown stop criteria: {self.stop_criteria}

Error message

Unknown stop criteria: {self.stop_criteria}

What it means

Raised by Simulator._should_stop when the configured stop_criteria string matches neither 'exist_no_pending' nor 'all_done'. The simulator loop calls _should_stop each tick to decide termination; an unrecognized criteria means the simulation can never terminate correctly, so it fails fast instead of looping forever.

Source

Thrown at python/sglang/srt/debug_utils/schedule_simulator/simulator.py:74

            step_records.extend(
                gpu.get_step_record(self.step) for gpu in self.gpu_states
            )
            self._log_step()
            self._record_metrics()
            self.step += 1

        return SimulationResult(step_records=step_records, summary=self._get_summary())

    def _should_stop(self) -> bool:
        if self.max_steps is not None and self.step >= self.max_steps:
            return True
        if self.stop_criteria == "exist_no_pending":
            return any(not gpu.pending_requests for gpu in self.gpu_states)
        if self.stop_criteria == "all_done":
            return not any(
                gpu.pending_requests or gpu.running_requests for gpu in self.gpu_states
            )
        raise ValueError(f"Unknown stop criteria: {self.stop_criteria}")

    def _route_requests(self, incoming_requests: List[SimRequest]) -> None:
        for req in incoming_requests:
            gpu_id = self.router.route(req)
            if gpu_id < self.num_gpus_per_engine:
                self.gpu_states[gpu_id].pending_requests.append(req)

    def _schedule_all_gpus(self) -> None:
        for gpu in self.gpu_states:
            self.scheduler.schedule(gpu)
            assert gpu.is_valid(), (
                f"GPU{gpu.gpu_id} invalid after scheduling "
                f"({gpu.total_seq_len()=}, {gpu.max_total_tokens=})"
            )

    def _execute_step(self) -> None:
        for gpu in self.gpu_states:
            gpu.execute_step()

View on GitHub (pinned to 0132848349)

Solutions

  1. Set stop_criteria to 'exist_no_pending' or 'all_done' exactly
  2. Check for hyphens vs underscores and casing typos in the config
  3. If constructing Simulator programmatically, assert the value against the two literals before run()

Example fix

# before
sim = Simulator(..., stop_criteria='all-done')

# after
sim = Simulator(..., stop_criteria='all_done')
Defensive patterns

Strategy: validation

Validate before calling

VALID_STOP = {'exist_no_pending', 'all_done'}
if sim_config.stop_criteria not in VALID_STOP:
    raise ConfigError(f'stop_criteria must be one of {sorted(VALID_STOP)}')

Type guard

def is_valid_stop_criteria(value: str) -> bool:
    return value in ('exist_no_pending', 'all_done')

Try / catch

try:
    sim.run()
except ValueError as e:
    if 'Unknown stop criteria' in str(e):
        fix_config_and_retry()
    else:
        raise

Prevention

When it happens

Trigger: Constructing Simulator(stop_criteria='...') or passing a CLI/config value other than exist_no_pending / all_done, then calling simulator.run().

Common situations: Typos in config files or CLI args ('alldone', 'all-done'); version skew where a criteria name was renamed; hand-rolled scripts constructing the Simulator directly.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/3977e6cb3f005cc1. Report an issue: GitHub.