{"record":{"id":"4c3266b54c961374","repo":"sgl-project/sglang","slug":"stop-regex-stop-regex-strs-r-is-unavailable-when","errorCode":null,"errorMessage":"stop_regex={stop_regex_strs!r} is unavailable when skip_tokenizer_init=True (requires tokenizer to decode tokens to text for matching).","messagePattern":"stop_regex=(.+?) is unavailable when skip_tokenizer_init=True \\(requires tokenizer to decode tokens to text for matching\\)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/sampling/sampling_params.py","lineNumber":329,"sourceCode":"    tokenizer, stop_strs, stop_regex_strs, min_new_tokens=0\n):\n    \"\"\"Raise ValueError if tokenizer-dependent features are used without a tokenizer.\n\n    String-based stop conditions (stop_strs, stop_regex_strs) require tokenizer.decode()\n    to convert output token IDs to text for matching. min_new_tokens requires the\n    tokenizer's eos_token_id to penalize. When skip_tokenizer_init=True, these cannot\n    be used.\n    \"\"\"\n    if tokenizer is not None:\n        return\n\n    if stop_strs:\n        raise ValueError(\n            f\"stop={stop_strs!r} is unavailable when skip_tokenizer_init=True \"\n            \"(requires tokenizer to decode tokens to text for matching).\"\n        )\n    if stop_regex_strs:\n        raise ValueError(\n            f\"stop_regex={stop_regex_strs!r} is unavailable when skip_tokenizer_init=True \"\n            \"(requires tokenizer to decode tokens to text for matching).\"\n        )\n    if min_new_tokens > 0:\n        raise ValueError(\n            f\"min_new_tokens={min_new_tokens} is unavailable when skip_tokenizer_init=True \"\n            \"(requires tokenizer for eos_token_id).\"\n        )\n","sourceCodeStart":311,"sourceCodeEnd":338,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/sampling/sampling_params.py#L311-L338","documentation":"With --skip-tokenizer-init, regex-based stop conditions are unsupported for the same reason as string stops: matching stop_regex requires decoding tokens to text, and no tokenizer exists. raise_if_tokenizer_required rejects stop_regex_strs during normalize().","triggerScenarios":"Server started with --skip-tokenizer-init and a request sets SamplingParams(stop_regex=[\"\\n\\nUser:\"]) or a string entry inside stop that is treated as a regex.","commonSituations":"Agents/chat loops that stop on a pattern (e.g. turn delimiter) pointed at a tokenizer-free endpoint; porting configs from a normal server to a skip-tokenizer benchmark server.","solutions":["Drop stop_regex and use stop_token_ids with the ids of concrete delimiter tokens.","Or run the server with a tokenizer (remove --skip-tokenizer-init)."],"exampleFix":"# before\nSamplingParams(stop_regex=[r\"\\n\\nUser:\"])  # with --skip-tokenizer-init\n# after\nSamplingParams(stop_token_ids=[tokenizer.convert_tokens_to_ids(t) for t in (\"\\n\\n\", \"User\", \":\")])","handlingStrategy":"type-guard","validationCode":"if skip_tokenizer_init:\n    params.pop('stop_regex', None)  # or reject early with your own message","typeGuard":"def regex_stop_ok_without_tokenizer(params: dict) -> bool:\n    return not params.get('stop_regex')","tryCatchPattern":null,"preventionTips":["Treat --skip-tokenizer-init endpoints as ids-in/ids-out; audit any text-matching params before switching."],"tags":["skip-tokenizer-init","stop-regex","sampling-params","sglang"],"backgroundTag":"feature-requires-tokenizer","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}