{"record":{"id":"743535dad9e74970","repo":"sgl-project/sglang","slug":"denoising-step-list-must-end-with-0-got-schedule","errorCode":null,"errorMessage":"denoising_step_list must end with 0, got {schedule}","messagePattern":"denoising_step_list must end with 0, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/sana_wm/self_forcing.py","lineNumber":207,"sourceCode":"        for stale in range(chunk_idx):\n            if stale in keep:\n                continue\n            kv_cache[stale] = [\n                [None] * _NUM_STREAM_CACHE_SLOTS for _ in range(num_blocks)\n            ]\n\n    # ----------------------------------------------------------------- #\n    # Per-chunk flow-Euler sigma schedule\n    # ----------------------------------------------------------------- #\n    @staticmethod\n    def build_per_chunk_sigmas(denoising_step_list) -> list[float]:\n        \"\"\"Explicit flow-Euler sigmas for one chunk's short self-forcing schedule.\n\n        The ``denoising_step_list`` (e.g. (1000, 960, 889, 727, 0)) must end with\n        0; sigmas are the non-terminal steps divided by 1000.\"\"\"\n        schedule = list(denoising_step_list)\n        if len(schedule) < 2 or schedule[-1] != 0:\n            raise ValueError(f\"denoising_step_list must end with 0, got {schedule}\")\n        return [float(t) / 1000.0 for t in schedule[:-1]]\n","sourceCodeStart":189,"sourceCodeEnd":209,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/sana_wm/self_forcing.py#L189-L209","documentation":"build_per_chunk_sigmas converts a denoising_step_list such as (1000, 960, 889, 727, 0) into flow-Euler sigmas. The schedule must have at least 2 entries and its last entry must be 0 (terminal timestep); sigmas are the non-terminal steps divided by 1000. Violating either invariant raises this ValueError.","triggerScenarios":"Passing a schedule like (1000, 960, 889) with no terminal 0, a single-element list, or a schedule normalized to sigmas (0.0 terminal in wrong units) instead of raw timesteps.","commonSituations":"Copying a sigma list from a diffusers config directly instead of the timestep list; truncating a schedule when reducing step counts; hand-editing denoising_step_list in server args.","solutions":["Append a terminal 0 to the step list, e.g. (1000, 960, 889, 727, 0)","Use the official SANA-WM self-forcing schedule values verbatim","Ensure entries are integer timesteps in [0,1000], not normalized sigmas"],"exampleFix":"# before\nbuild_per_chunk_sigmas([1000, 960, 889])\n# after\nbuild_per_chunk_sigmas([1000, 960, 889, 727, 0])","handlingStrategy":"validation","validationCode":"def valid_schedule(steps):\n    steps = list(steps)\n    return len(steps) >= 2 and steps[-1] == 0\nassert valid_schedule(denoising_step_list), denoising_step_list","typeGuard":"def is_terminal_zero_schedule(steps) -> bool:\n    steps = list(steps)\n    return len(steps) >= 2 and steps[-1] == 0 and all(isinstance(t, int) and 0 <= t <= 1000 for t in steps)","tryCatchPattern":"null","preventionTips":["Copy schedules from official configs verbatim","Validate schedule invariants when parsing server args","Remember entries are timesteps (0-1000), not sigmas"],"tags":["sana-wm","self-forcing","sigma-schedule","denoising-steps","valueerror"],"backgroundTag":"invalid-schedule-config","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}