{"record":{"id":"1ae0daa37b17df01","repo":"sgl-project/sglang","slug":"kv-canary-realkvsource-page-size-must-be-1-go","errorCode":null,"errorMessage":"kv-canary: RealKvSource.page_size must be >= 1, got {self.page_size}","messagePattern":"kv-canary: RealKvSource\\.page_size must be >= 1, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/kv_canary/verify.py","lineNumber":95,"sourceCode":"    Fields:\n        tensor: The source tensor, any shape such that the access pattern above yields ``num_bytes_per_token``\n            uint8 bytes per slot. Dtype is whatever the underlying pool uses; the canary views the relevant\n            bytes via ``.view(torch.uint8)``.\n        page_size: Number of slots packed into one row of dim 0. ``>= 1``.\n        num_bytes_per_token: Bytes per slot in the dim-1 strip the canary reads. Must be a positive\n            multiple of 16.\n        read_bytes: Leading bytes (out of ``num_bytes_per_token``) per slot folded into the fingerprint.\n            Must be a positive multiple of 16, ``<= num_bytes_per_token``.\n    \"\"\"\n\n    tensor: torch.Tensor\n    page_size: int\n    num_bytes_per_token: int\n    read_bytes: int\n\n    def __post_init__(self) -> None:\n        if self.page_size < 1:\n            raise ValueError(\n                f\"kv-canary: RealKvSource.page_size must be >= 1, got {self.page_size}\"\n            )\n        if self.num_bytes_per_token <= 0 or self.num_bytes_per_token % 16 != 0:\n            raise ValueError(\n                f\"kv-canary: RealKvSource.num_bytes_per_token must be a positive multiple of 16, \"\n                f\"got {self.num_bytes_per_token}\"\n            )\n        if (\n            self.read_bytes <= 0\n            or self.read_bytes > self.num_bytes_per_token\n            or self.read_bytes % 16 != 0\n        ):\n            raise ValueError(\n                f\"kv-canary: RealKvSource.read_bytes must be a positive multiple of 16 in \"\n                f\"(0, num_bytes_per_token={self.num_bytes_per_token}], got {self.read_bytes}\"\n            )\n        if self.tensor.ndim < 2:\n            raise ValueError(","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/kv_canary/verify.py#L77-L113","documentation":"RealKvSource is a frozen dataclass describing one piece of real KV memory the canary fingerprints; __post_init__ validates page_size >= 1 because it is used to convert token positions into page indices. Zero or negative page sizes would produce garbage indices, so ValueError is raised at construction.","triggerScenarios":"Constructing RealKvSource(page_size=0, ...) or with a negative value, e.g. reading page size from a config where 0 means 'unset'.","commonSituations":"Config plumbing where page_size defaults to 0 before the allocator initializes; deriving page size from a division that yielded 0.","solutions":["Pass the actual page size from the KV allocator / memory pool config","Guard configs: if page_size <= 0, raise or fix upstream before constructing the source"],"exampleFix":"# before\nsrc = RealKvSource(page_size=0, ...)\n# after\nsrc = RealKvSource(page_size=pool.page_size, ...)","handlingStrategy":"validation","validationCode":"assert page_size >= 1, page_size","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Propagate page size from the allocator config; never default it to 0"],"tags":["kv-cache","config-validation","page-size"],"backgroundTag":"invalid-config-value","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}