{"record":{"id":"afbfb4ac05e3396a","repo":"sgl-project/sglang","slug":"rids-to-check-cannot-be-used-in-pp-mode","errorCode":null,"errorMessage":"rids_to_check cannot be used in PP mode","messagePattern":"rids_to_check cannot be used in PP mode","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/disaggregation/decode.py","lineNumber":1082,"sourceCode":"                    prefetched[1].cancel()\n\n        self.pending_reqs = remaining\n\n        for decode_req, prefill_dp_rank in resolved:\n            decode_req.kv_receiver.init(prefill_dp_rank)\n\n    def pop_preallocated(\n        self,\n        rids_to_check: Optional[List[str]] = None,\n        pp_good_rids: Optional[List[str]] = None,\n        pp_bad_rids: Optional[List[str]] = None,\n    ) -> Tuple[List[DecodeRequest], List[DecodeRequest]]:\n        \"\"\"Pop the preallocated requests from the pending queue (FIFO).\"\"\"\n        is_pp_mode = self.pp_size > 1\n        if is_pp_mode and (pp_good_rids is None or pp_bad_rids is None):\n            raise ValueError(\"PP consensus is required when pp_size > 1\")\n        if is_pp_mode and rids_to_check is not None:\n            raise ValueError(\"rids_to_check cannot be used in PP mode\")\n\n        self._resolve_pending_reqs()\n        self._update_handshake_waiters(rids_to_check, pp_good_rids, pp_bad_rids)\n        if is_pp_mode:\n            rids_to_check = set(pp_good_rids) | set(pp_bad_rids)\n\n        failed_reqs = []\n        preallocated_reqs = []\n        indices_to_remove = set()\n\n        # We need to make sure that the sum of inflight tokens and allocatable tokens is greater than maximum input+output length of each inflight request\n        # Otherwise it is possible for one request running decode out of memory, while all other requests are in the transfer queue that cannot be retracted.\n        retractable_tokens = sum(\n            len(r.origin_input_ids) + len(r.output_ids)\n            for r in self.scheduler.running_batch.reqs\n        )\n\n        uses_swa_tail_prealloc = self._uses_swa_tail_prealloc()","sourceCodeStart":1064,"sourceCodeEnd":1100,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/disaggregation/decode.py#L1064-L1100","documentation":"Companion guard to the PP consensus check: in PP mode (pp_size > 1), pop_preallocated rejects rids_to_check because request resolution must be driven by the pipeline-wide pp_good_rids/pp_bad_rids consensus, not a per-stage check list. Passing both is contradictory.","triggerScenarios":"Calling pop_preallocated with pp_size > 1 and a non-None rids_to_check (alongside or instead of the consensus lists).","commonSituations":"Single-PP scheduler/test code reused on a PP deployment; upgrading a codebase where rids_to_check was the old API and the PP path was added later.","solutions":["Remove the rids_to_check argument and supply pp_good_rids/pp_bad_rids in PP mode","Branch caller code on pp_size: use rids_to_check only when pp_size == 1"],"exampleFix":"# before\ngood, bad = queue.pop_preallocated(rids_to_check=rids, pp_good_rids=g, pp_bad_rids=b)\n# after\nif queue.pp_size > 1:\n    good, bad = queue.pop_preallocated(pp_good_rids=g, pp_bad_rids=b)\nelse:\n    good, bad = queue.pop_preallocated(rids_to_check=rids)","handlingStrategy":"validation","validationCode":"if queue.pp_size > 1:\n    assert rids_to_check is None, 'use pp_good_rids/pp_bad_rids in PP mode'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Branch on pp_size at the call site instead of passing both styles"],"tags":["disaggregation","pipeline-parallel","api-misuse","argument-conflict"],"backgroundTag":"invalid-argument-combination","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}