sgl-project/sglang · error · ValueError

DFLASH mask_token must be a non-empty string, got {mask_toke

Error message

DFLASH mask_token must be a non-empty string, got {mask_token!r}.

What it means

Thrown during DFLASH worker initialization when the configured mask_token is not a non-empty string. DFLASH drafts rely on a mask token to represent masked positions; the worker validates it before resolving its token id against the target vocab. Passing None, an int, or '' fails here with the offending value echoed.

Source

Thrown at python/sglang/srt/speculative/dflash_worker_v2.py:876

            )

            assert self._draft_block_end_buf is not None
            block_end = self._draft_block_end_buf[:bs]
            torch.add(draft_prefix_lens, block_size, out=block_end)
            assign_req_to_token_pool_func(
                req_pool_indices,
                self.draft_model_runner.req_to_token_pool.req_to_token,
                draft_prefix_lens,
                block_end,
                verify_out_cache_loc_2d.reshape(-1),
                bs,
            )

    def _resolve_mask_token_id(
        self, *, mask_token: str, mask_token_id: Optional[int] = None
    ) -> int:
        if not isinstance(mask_token, str) or not mask_token:
            raise ValueError(
                f"DFLASH mask_token must be a non-empty string, got {mask_token!r}."
            )

        vocab_size = int(self.target_worker.model_runner.model_config.vocab_size)
        if mask_token_id is not None:
            resolved_id = int(mask_token_id)
            if resolved_id >= vocab_size:
                raise ValueError(
                    "DFLASH mask_token_id is outside the target vocab size. "
                    f"mask_token_id={resolved_id}, vocab_size={vocab_size}. "
                    f"This likely means mask_token={mask_token!r} requires vocab expansion beyond the model's embedding size. "
                    "SGLang does not support resizing target embeddings for DFLASH yet."
                )

            tokenizer = getattr(self.target_worker, "tokenizer", None)
            if tokenizer is not None:
                token_id_from_vocab = tokenizer.get_vocab().get(mask_token, None)
                if (

View on GitHub (pinned to 0132848349)

Solutions

  1. Set the mask token as its string form, e.g. --speculative-dflash-mask-token "<mask>" (or the model's documented mask token string)
  2. If you only know the id, find the token string via tokenizer.decode([id]) and pass that string
  3. Remove empty-string overrides so the model's default mask token applies

Example fix

# before
--speculative-algorithm DFLASH \
--speculative-dflash-mask-token ""

# after
--speculative-algorithm DFLASH \
--speculative-dflash-mask-token "<|mask|>"
Defensive patterns

Strategy: validation

Validate before calling

mask_token = server_args.speculative_dflash_mask_token
assert isinstance(mask_token, str) and mask_token, (
    f"mask_token must be a non-empty string, got {mask_token!r}"
)

Type guard

def is_valid_mask_token(v) -> bool:
    return isinstance(v, str) and len(v) > 0

Prevention

When it happens

Trigger: Server/speculative config where speculative_dflash_mask_token is omitted from the config class default and ends up None, set to an integer id by mistake, or set to the empty string in a launch script/JSON config.

Common situations: Hand-written launch scripts or overrides that set the mask token to an id (e.g. 128000) instead of the string form; config migration dropping the field; YAML/JSON quoting mistakes producing non-string values.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/44abe4a1f9d00c76. Report an issue: GitHub.