{"record":{"id":"ef63009cdd9f31d4","repo":"sgl-project/sglang","slug":"grammar-mask-max-rows-must-be-positive-got-max-r","errorCode":null,"errorMessage":"Grammar mask max_rows must be positive, got {max_rows}","messagePattern":"Grammar mask max_rows must be positive, got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/constrained/base_grammar_backend.py","lineNumber":307,"sourceCode":"            copied_value = value.copy()\n            copied_value.maybe_init_reasoning(require_reasoning)\n            return copied_value, True\n        value = self.executor.submit(self._init_value_dispatch, key, require_reasoning)\n        return value, False\n\n    def set_cache(self, key: Tuple[str, str], value: BaseGrammarObject):\n        self.cache[key] = value\n\n    def reset(self):\n        self.cache.clear()\n\n\ndef register_vocab_mask_buffer(\n    name: str, vocab_mask: torch.Tensor, max_rows: int\n) -> torch.Tensor:\n    \"\"\"Register a fixed-capacity mask buffer, preserving an equivalent one.\"\"\"\n    if max_rows <= 0:\n        raise ValueError(f\"Grammar mask max_rows must be positive, got {max_rows}\")\n    if vocab_mask.ndim == 0 or vocab_mask.shape[0] != max_rows:\n        raise ValueError(\n            f\"Grammar mask buffer {name!r} must have {max_rows} rows, \"\n            f\"got shape {tuple(vocab_mask.shape)}\"\n        )\n\n    buffers = get_resources().buffers\n    existing = buffers.get(name)\n    if existing is not None:\n        if (\n            existing.shape != vocab_mask.shape\n            or existing.dtype != vocab_mask.dtype\n            or existing.device != vocab_mask.device\n        ):\n            raise RuntimeError(\n                f\"Grammar mask buffer {name!r} was already initialized as \"\n                f\"{tuple(existing.shape)}, {existing.dtype}, {existing.device}; \"\n                f\"new buffer is {tuple(vocab_mask.shape)}, {vocab_mask.dtype}, \"","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/constrained/base_grammar_backend.py#L289-L325","documentation":"The grammar-backend mask buffer API requires a strictly positive row capacity; register_vocab_mask_buffer raises ValueError when max_rows <= 0 because a zero/negative-capacity buffer cannot hold any grammar mask rows.","triggerScenarios":"Calling register_vocab_mask_buffer(name, vocab_mask, max_rows) with max_rows=0 or negative, e.g. when the caller computes max_rows from request batch size or grammar count and that computation yields 0 (no active grammar requests).","commonSituations":"Scheduler/attention code sizing the constrained-decoding mask buffer from an empty batch or a misconfigured max_num_seqs of 0; refactors that pass a placeholder capacity of 0 during initialization.","solutions":["Ensure max_rows is derived from a positive quantity (e.g. max(1, num_active_grammar_requests) or the configured max running request count)","Check server args like --max-running-requests / batch-size settings for zero values","If registering lazily, skip registration when there are no grammar requests instead of passing 0"],"exampleFix":"// before\nbackend.register_vocab_mask_buffer(\"vocab_mask\", mask, num_grammar_reqs)  # 0 when idle\n// after\nif num_grammar_reqs > 0:\n    backend.register_vocab_mask_buffer(\"vocab_mask\", mask, num_grammar_reqs)","handlingStrategy":"validation","validationCode":"if max_rows <= 0:\n    raise SkipRegistration(\"no grammar rows\")\nbackend.register_vocab_mask_buffer(name, vocab_mask, max_rows)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Compute buffer capacity from config (max running requests), never from instantaneous batch state","Assert capacity > 0 in tests covering grammar buffer setup"],"tags":["grammar","constrained-decoding","validation"],"backgroundTag":"invalid-argument-validation","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}