sgl-project/sglang · error · std::runtime_error

Unknown match_type: '${param_.match_type}'. Must be 'BFS' or

Error message

Unknown match_type: '${param_.match_type}'. Must be 'BFS' or 'PROB'.

What it means

The matcher supports exactly two match strategies selected by param_.match_type: 'BFS' (recency-based buildRecency) and 'PROB' (frequency-based buildFrequency). Any other string is rejected at dispatch time inside batchMatch.

Source

Thrown at python/sglang/kernels/jit/csrc/ngram_corpus/ngram.cpp:166

  if (state_ids.size() != tokens.size() || state_ids.size() != total_lens.size()) {
    throw std::runtime_error("batchMatch expects state_ids, tokens, and total_lens to match in size");
  }

  std::unique_lock<std::mutex> lock(mutex_);

  using TrieResultBuildFn =
      Result (Trie::*)(const int32_t*, size_t, int32_t, size_t, const Param&, MatchState&, size_t) const;
  using SamResultBuildFn = Result (SuffixAutomaton::*)(const int32_t*, size_t, int32_t, size_t, const Param&) const;
  TrieResultBuildFn trie_result_build_fn;
  SamResultBuildFn sam_result_build_fn;
  if (param_.match_type == "BFS") {
    trie_result_build_fn = &Trie::buildRecency;
    sam_result_build_fn = &SuffixAutomaton::buildRecency;
  } else if (param_.match_type == "PROB") {
    trie_result_build_fn = &Trie::buildFrequency;
    sam_result_build_fn = &SuffixAutomaton::buildFrequency;
  } else {
    throw std::runtime_error("Unknown match_type: '" + param_.match_type + "'. Must be 'BFS' or 'PROB'.");
  }

  // All budget values are loop-invariant (mutex_ held, sams_ won't change).
  const size_t num_sams = sams_.size();
  const auto total_draft_token_num = param_.get_draft_token_num(tokens.size());
  const size_t total_sam_budget =
      num_sams > 0 ? std::min(param_.external_sam_budget, total_draft_token_num) : size_t{0};
  const size_t per_sam_budget = num_sams > 0 ? total_sam_budget / num_sams : size_t{0};
  const size_t trie_budget = total_draft_token_num - (per_sam_budget * num_sams);

  Result merged;
  for (size_t i = 0; i < state_ids.size(); ++i) {
    const auto& suffix = tokens[i];
    if (suffix.empty()) {
      throw std::runtime_error("batchMatch received an empty token tail");
    }

    auto& state = match_state_[state_ids[i]];

View on GitHub (pinned to 0132848349)

Solutions

  1. Set match_type to exactly "BFS" or "PROB"
  2. Normalize/uppercase the config string before constructing Param
  3. Validate match_type at config-parse time and fail fast with a clear message

Example fix

// before
param.match_type = "bfs"; // throws in batchMatch
// after
param.match_type = "BFS";
Defensive patterns

Strategy: validation

Validate before calling

if (param.match_type != "BFS" && param.match_type != "PROB") throw std::invalid_argument("match_type must be BFS or PROB");

Type guard

bool match_type_valid(const std::string& s) { return s == "BFS" || s == "PROB"; }

Prevention

When it happens

Trigger: Constructing/using Ngram with param.match_type set to anything other than "BFS" or "PROB" (e.g. "bfs" lowercase, "probabilistic", typo) and then calling batchMatch.

Common situations: Case mismatch from config strings ('bfs' vs 'BFS'); new/renamed strategy string after a version change; user-supplied config value passed through unvalidated.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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