{"record":{"id":"6799b5286ac205ca","repo":"sgl-project/sglang","slug":"pp-consensus-is-required-when-pp-size-1","errorCode":null,"errorMessage":"PP consensus is required when pp_size > 1","messagePattern":"PP consensus is required when pp_size > 1","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/disaggregation/decode.py","lineNumber":1080,"sourceCode":"                prefetched = self._prefill_dp_rank_queries.pop(bootstrap_addr, None)\n                if prefetched is not None:\n                    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        )","sourceCodeStart":1062,"sourceCodeEnd":1098,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/disaggregation/decode.py#L1062-L1098","documentation":"pop_preallocated in PP (pipeline-parallel > 1) mode requires the cross-PP consensus sets pp_good_rids/pp_bad_rids so all pipeline stages agree on which requests were successfully preallocated. When pp_size > 1 and either list is None, consensus cannot be established and the method raises.","triggerScenarios":"Calling pop_preallocated with self.pp_size > 1 and pp_good_rids=None or pp_bad_rids=None — e.g. a scheduler path or test invoking it without forwarding the PP handshake results.","commonSituations":"New scheduler code paths (or tests) that call pop_preallocated with only rids_to_check; refactors dropping the consensus arguments; single-node code reused against a PP deployment.","solutions":["Pass both pp_good_rids and pp_bad_rids (from the PP handshake/consensus step) whenever pp_size > 1","Do not pass rids_to_check in PP mode — use the consensus lists instead","In tests, construct the consensus lists explicitly when simulating PP mode"],"exampleFix":"# before\ngood, bad = queue.pop_preallocated()  # pp_size > 1\n# after\ngood, bad = queue.pop_preallocated(\n    pp_good_rids=good_rids, pp_bad_rids=bad_rids)","handlingStrategy":"validation","validationCode":"if queue.pp_size > 1:\n    assert pp_good_rids is not None and pp_bad_rids is not None","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always forward PP handshake results into pop_preallocated","Centralize the pop call in one scheduler helper that handles both modes"],"tags":["disaggregation","pipeline-parallel","consensus","api-misuse"],"backgroundTag":"missing-required-argument","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}