{"record":{"id":"19d734bc432c6e3d","repo":"sgl-project/sglang","slug":"min-hits-must-be-positive-got-min-hits","errorCode":null,"errorMessage":"min_hits must be positive, got {min_hits}","messagePattern":"min_hits must be positive, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/multimodal/kimi_k3_vit_cuda_graph_runner.py","lineNumber":48,"sourceCode":"    graph: torch.cuda.CUDAGraph\n    input_buffer: torch.Tensor\n    outputs: Tuple[torch.Tensor, ...]\n    metadata: KimiK3VisionForwardMetadata\n\n\nclass KimiK3ViTCudaGraphRunner:\n    def __init__(\n        self,\n        tower: KimiK3VisionTower,\n        *,\n        capacity: int,\n        min_hits: int,\n        max_seqlen: int | None = None,\n    ) -> None:\n        if capacity <= 0:\n            raise ValueError(f\"capacity must be positive, got {capacity}\")\n        if min_hits <= 0:\n            raise ValueError(f\"min_hits must be positive, got {min_hits}\")\n        if max_seqlen is not None and max_seqlen <= 0:\n            raise ValueError(f\"max_seqlen must be positive, got {max_seqlen}\")\n        self.tower = tower\n        self.capacity = capacity\n        self.min_hits = min_hits\n        self.max_seqlen = max_seqlen\n        self.graphs: dict[Hashable, _CapturedVisionGraph] = {}\n        self.seen: OrderedDict[Hashable, int] = OrderedDict()\n        self.failed_keys: set[Hashable] = set()\n        self._graph_memory_pool: Any = None\n        self._capacity_logged = False\n        self._max_seqlen_logged = False\n        logger.info(\n            \"Kimi-K3 ViT CUDA graph: capacity=%d min_hits=%d max_seqlen=%s\",\n            capacity,\n            min_hits,\n            max_seqlen,\n        )","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/multimodal/kimi_k3_vit_cuda_graph_runner.py#L30-L66","documentation":"The Kimi-K3 ViT CUDA graph runner's min_hits threshold (how many times a shape must be seen before capturing a graph) must be positive; min_hits <= 0 is rejected in __init__ to avoid capturing graphs for transient shapes.","triggerScenarios":"Constructing the runner with min_hits=0 or negative, e.g. from a default of 0 in a config struct or an env var parsed as int('0').","commonSituations":"Tuning scripts sweeping min_hits from 0; misparsed SGLANG_* env variable yielding 0.","solutions":["Set min_hits >= 1 (2-3 is typical to avoid one-off captures)","Validate/normalize the value at config-parse time: max(1, min_hits)","Check the env var actually exporting the intended number"],"exampleFix":"// before\nrunner = KimiK3VitCudaGraphRunner(tower=t, capacity=8, min_hits=cfg.min_hits)  # cfg.min_hits == 0\n// after\nrunner = KimiK3VitCudaGraphRunner(tower=t, capacity=8, min_hits=max(1, cfg.min_hits))","handlingStrategy":"validation","validationCode":"assert isinstance(min_hits, int) and min_hits >= 1, f\"min_hits must be >= 1, got {min_hits}\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default min_hits to 2-3 in configs","Sanitize env-derived ints before passing them in"],"tags":["cuda-graph","kimi-k3","config-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}