sgl-project/sglang · error · Error
delta payload size mismatch: expected ${expectedSize}, got $
Error message
delta payload size mismatch: expected ${expectedSize}, got ${restored.length} What it means
Thrown by ngram_corpus Param::parse when two configured ranges overlap: the parser marks each position it fills, and filling an already-marked position means the config assigns a value to the same token position twice. Ranges must be disjoint.
Source
Thrown at python/sglang/multimodal_gen/apps/realtime_webui/app.js:1075
}
return items;
}
async function gunzipBytes(payload) {
if (typeof DecompressionStream === "undefined") {
throw new Error("This browser does not support gzip stream decoding");
}
const stream = new Blob([payload]).stream().pipeThrough(new DecompressionStream("gzip"));
return new Uint8Array(await new Response(stream).arrayBuffer());
}
async function restoreDeltaGzipRawRgb(header, payload) {
const frameBytes = Number(header.bytes_per_frame);
const count = Number(header.num_frames);
const expectedSize = frameBytes * count;
const restored = await gunzipBytes(payload);
if (restored.length !== expectedSize) {
throw new Error(`delta payload size mismatch: expected ${expectedSize}, got ${restored.length}`);
}
let previous = header.delta_reference === "previous-frame" ? lastRawRgbFrame : null;
if (header.delta_reference === "previous-frame" && !previous) {
throw new Error("Missing previous frame for delta payload");
}
for (let f = 0; f < count; f++) {
const current = f * frameBytes;
if (previous) {
for (let i = 0; i < frameBytes; i++) {
restored[current + i] ^= previous[i];
}
}
previous = restored.slice(current, current + frameBytes);
}
return restored;
}
async function framePayloadToImageData(header, payload) {View on GitHub (pinned to 0132848349)
Solutions
- Make all ranges in the config disjoint, e.g. '2-4|8 5-8|3' instead of '2-4|8 3-5|3'
- Remember ranges are inclusive on both ends — adjacent ranges must not share an endpoint
- Write a quick Python check that merges/validates interval overlap before passing the string to C++
Example fix
# before
param.resetBatchReturnTokenNum("2-4|8 3-5|3")
# after
param.resetBatchReturnTokenNum("2-4|8 5-8|3") Defensive patterns
Strategy: validation
Validate before calling
ivs = sorted(tuple(map(int, s.split("|")[0].split("-"))) for s in cfg.split())
for (a1, b1), (a2, b2) in zip(ivs, ivs[1:]):
assert b1 < a2, f"overlapping ranges {a1}-{b1} and {a2}-{b2}" Type guard
def ranges_disjoint(cfg: str) -> bool:
ivs = sorted(tuple(map(int, s.split("|")[0].split("-"))) for s in cfg.split())
return all(b1 < a2 for (_, b1), (a2, _) in zip(ivs, ivs[1:])) Try / catch
try:
param.resetBatchReturnTokenNum(cfg)
except RuntimeError as e:
if "repeated position" in str(e):
raise ValueError(f"overlapping ranges in {cfg!r}; make them disjoint") from e
raise Prevention
- Treat ranges as inclusive on both ends — adjacent ranges must not share endpoints
- Auto-merge overlapping intervals before serializing the config
- Add a config round-trip test that parses and re-serializes
When it happens
Trigger: resetBatchReturnTokenNum with overlapping segments such as '2-4|8 3-5|3' — position 3 and 4 are covered by both ranges, so mark[L] is already true on the second pass.
Common situations: Appending a new range to an existing config without checking for overlap, or ranges like '2-4|8 4-6|3' that share an endpoint (inclusive ranges).
Related errors
- This browser cannot encode H.264 MP4
- H.264 encoder did not return MP4 decoder config
- This browser does not support gzip stream decoding
- Component residency must use COMPONENT=MODE, got {assignment
- Component residency selector cannot be empty
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/62ddc528c5b1693c.
Report an issue: GitHub.