sgl-project/sglang · error · ValueError
External corpus '{corpus_id}' already exists. Remove it befo
Error message
External corpus '{corpus_id}' already exists. Remove it before adding a new corpus with the same id. What it means
Ngram_corpus tracks loaded external corpora by corpus_id in _corpus_token_counts. load_external_corpus_named refuses to overwrite: re-loading an id that already exists raises this ValueError, telling the caller to remove the old corpus first.
Source
Thrown at python/sglang/srt/speculative/cpp_ngram/ngram_corpus.py:66
self._next_state_id += 1
self._req_id_to_state_id[req_id] = sid
return sid
def batch_put(self, batch_tokens: List[List[int]]):
self._obj.insert(batch_tokens)
def synchronize(self):
self._obj.synchronize() # type: ignore
@property
def remaining_token_budget(self) -> int:
return self.external_corpus_max_tokens - self._total_loaded_tokens
def load_external_corpus_named(
self, corpus_id: str, chunks: Iterable[Sequence[int]]
) -> int:
if corpus_id in self._corpus_token_counts:
raise ValueError(
f"External corpus '{corpus_id}' already exists. Remove it before "
f"adding a new corpus with the same id."
)
# Note(kpham-sgl): remaining_token_budget is stale (e.g if there are removes
# during the load), which makes the budget more conservative than it should be.
# This is acceptable because otherwise load_external_corpus_named would need to check the budget after each chunk,
# which would be inefficient.
_, loaded_token_count = self._obj.load_external_corpus_named(
corpus_id, chunks, self.remaining_token_budget
)
return loaded_token_count
# Commit corpus bookkeeping after successful load. Call only at background thread join.
# (or after synchronous load_external_corpus_named returns)
def commit_external_corpus_load(
self, corpus_id: str, loaded_token_count: int
) -> None:
self._corpus_token_counts[corpus_id] = loaded_token_countView on GitHub (pinned to 0132848349)
Solutions
- Remove the existing corpus first: remove_external_corpus(corpus_id), then reload
- Or use a new unique corpus_id for the updated corpus
Example fix
# before
manager.add_external_corpus("docs", chunks) # second time -> ValueError
# after
if "docs" in manager.list_external_corpora():
manager.remove_external_corpus("docs")
manager.add_external_corpus("docs", chunks) Defensive patterns
Strategy: validation
Validate before calling
if corpus_id in manager.list_external_corpora(): # or equivalent membership check
manager.remove_external_corpus(corpus_id)
manager.load_external_corpus_named(corpus_id, chunks) Try / catch
try:
manager.load_external_corpus_named(cid, chunks)
except ValueError as e:
if "already exists" in str(e):
manager.remove_external_corpus(cid)
manager.load_external_corpus_named(cid, chunks)
else:
raise Prevention
- Make add operations idempotent: remove-then-add wrapped in a helper
- Use versioned corpus ids (docs-v2) when updating content
When it happens
Trigger: Calling load_external_corpus_named (or add_external_corpus) twice with the same corpus_id without an intervening remove_external_corpus(corpus_id).
Common situations: Re-adding a corpus after editing its file (e.g. hot-reload of knowledge), retry logic that re-sends the same id, or duplicate ids from a config list.
Related errors
- External ngram corpus path does not exist: {path}
- A tokenizer is required to load an external ngram corpus.
- External ngram corpus max tokens must be positive.
- Invalid JSON in external ngram corpus at line {line_no}: {e.
- Invalid external ngram corpus record at line {line_no}: expe
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/dd96afee5a16e92b.
Report an issue: GitHub.