{"record":{"id":"69e556c009dbc0cb","repo":"vllm-project/vllm","slug":"local-tp-rank-local-tp-rank-must-be-in-0-loca","errorCode":null,"errorMessage":"local_tp_rank {local_tp_rank} must be in [0, {local_tp_size})","messagePattern":"local_tp_rank (.+?) must be in \\[0, (.+?)\\)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"vllm/distributed/kv_transfer/kv_connector/v1/moriio/moriio_connector.py","lineNumber":112,"sourceCode":"\n    logger.info(\"MoRIIO is available\")\n    MoRIIO_enabled = True\nexcept ImportError:\n    logger.error(\"MoRIIO is not available\")\n    MoRIIO_enabled = False\n\n\ndef is_moriio_available() -> bool:\n    return MoRIIO_enabled\n\n\ndef get_moriio_remote_tp_rank(\n    local_tp_rank: int, local_tp_size: int, remote_tp_size: int\n) -> int:\n    if local_tp_size <= 0 or remote_tp_size <= 0:\n        raise ValueError(\"TP sizes must be positive\")\n    if local_tp_rank < 0 or local_tp_rank >= local_tp_size:\n        raise ValueError(\n            f\"local_tp_rank {local_tp_rank} must be in [0, {local_tp_size})\"\n        )\n    if remote_tp_size == local_tp_size:\n        return local_tp_rank\n    if remote_tp_size > local_tp_size:\n        if remote_tp_size % local_tp_size != 0:\n            raise ValueError(\n                f\"remote tp_size {remote_tp_size} must be a multiple of local \"\n                f\"tp_size {local_tp_size} for heterogeneous-TP P/D\"\n            )\n        return local_tp_rank * (remote_tp_size // local_tp_size)\n    if local_tp_size % remote_tp_size != 0:\n        raise ValueError(\n            f\"local tp_size {local_tp_size} must be a multiple of remote \"\n            f\"tp_size {remote_tp_size} for heterogeneous-TP P/D\"\n        )\n    return local_tp_rank // (local_tp_size // remote_tp_size)\n","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/vllm/distributed/kv_transfer/kv_connector/v1/moriio/moriio_connector.py#L94-L130","documentation":"get_moriio_remote_tp_rank validates that local_tp_rank lies in [0, local_tp_size). The error means the rank passed in is outside the tensor-parallel group range, e.g. a global/DP-rank was supplied where a TP rank was expected, or the tp size used for validation is smaller than the real one.","triggerScenarios":"Passing get_tensor_model_parallel_rank vs world rank confusion; calling with local_tp_rank == local_tp_size (off-by-one from a range end); mixing remote tp size into the local validation slot.","commonSituations":"Refactors that change which rank variable is threaded into the connector; running with DP>1 and accidentally using the data-parallel rank; unit tests calling the helper with arbitrary ranks.","solutions":["Pass the true TP rank (e.g. vllm_config.parallel_config.tensor_parallel_rank / tp_group.rank_in_group), not world or DP rank","Confirm local_tp_size matches the instance's --tensor-parallel-size","Add an assert/range check at the call site before invoking the mapper"],"exampleFix":"// before\nremote_rank = get_moriio_remote_tp_rank(dp_rank, tp_size, remote_tp_size)\n\n// after\nremote_rank = get_moriio_remote_tp_rank(tp_rank, tp_size, remote_tp_size)","handlingStrategy":"validation","validationCode":"assert 0 <= tp_rank < tp_size, f\"tp_rank {tp_rank} out of range for tp_size {tp_size}\"","typeGuard":"def is_valid_tp_rank(rank, tp_size) -> bool:\n    return isinstance(rank, int) and isinstance(tp_size, int) and 0 <= rank < tp_size","tryCatchPattern":null,"preventionTips":["Always thread the tensor-parallel rank (tp_group rank-in-group), not world or DP rank, into connector helpers","Unit-test rank mapping across the full [0, tp_size) range"],"tags":["tensor-parallel","kv-transfer","validation"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}