sgl-project/sglang · error · Error
H.264 encoder did not return MP4 decoder config
Error message
H.264 encoder did not return MP4 decoder config
What it means
Thrown by ngram_corpus Param::parse when the left side of a config segment (before '|') does not split on '-' into exactly two tokens. The parser expects a positional range written as 'L-R', e.g. '2-4'.
Source
Thrown at python/sglang/multimodal_gen/apps/realtime_webui/app.js:709
duration: chunk.duration || 0,
key: chunk.type === "key",
});
}
function downloadBlob(blob, fileName) {
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
link.remove();
window.setTimeout(() => URL.revokeObjectURL(url), 1000);
}
function buildRecordingMp4() {
if (!recordingEncoderConfig.description) {
throw new Error("H.264 encoder did not return MP4 decoder config");
}
const width = recordingEncoderConfig.width;
const height = recordingEncoderConfig.height;
const samples = normalizeRecordingSamples(recordingSamples);
const mdatPayload = concatBytes(samples.map((sample) => sample.data));
const ftyp = mp4Box("ftyp", ascii("isom"), u32(0x200), ascii("isom"), ascii("iso2"), ascii("avc1"), ascii("mp41"));
const mdat = mp4Box("mdat", mdatPayload);
const firstSampleOffset = ftyp.byteLength + 8;
const moov = buildMoovBox({
width,
height,
samples,
firstSampleOffset,
avcConfig: new Uint8Array(recordingEncoderConfig.description),
});
return new Blob([ftyp, mdat, moov], { type: "video/mp4" });
}
View on GitHub (pinned to 0132848349)
Solutions
- Write the range as 'L-R|config' with a single ASCII hyphen, e.g. '2-4|8'
- Check for stray '-' characters inside numbers (e.g. '-2--4') that split into 3+ tokens
- Add a Python-side regex pre-check like ^\d+-\d+\|\d+( \d+-\d+\|\d+)*$ before calling into C++
Example fix
# before
param.resetBatchReturnTokenNum("2:4|8")
# after
param.resetBatchReturnTokenNum("2-4|8") Defensive patterns
Strategy: validation
Validate before calling
assert all(re.fullmatch(r"\d+-\d+\|\d+", s) for s in cfg.split()), "each range must be L-R with one hyphen"
Type guard
def has_wellformed_ranges(cfg: str) -> bool:
return all(len(s.split("|")[0].split("-")) == 2 for s in cfg.split()) Try / catch
try:
param.resetBatchReturnTokenNum(cfg)
except RuntimeError as e:
if "failed to get range" in str(e):
raise ValueError(f"range part malformed in {cfg!r}; use 'L-R|value'") from e
raise Prevention
- Always use a single ASCII hyphen in ranges
- Avoid negative numbers or stray dashes in the config
- Generate configs programmatically instead of hand-editing
When it happens
Trigger: resetBatchReturnTokenNum receives a segment like '2|8' (range uses wrong separator), '2-4-6' (three range tokens), or '24|8' (missing dash), so splitting part[0] on '-' yields a vector whose size != 2.
Common situations: Using ':' or '..' instead of '-' in range specs, negative or malformed numbers producing extra '-' splits, or hand-edited config strings with a mistyped separator.
Related errors
- This browser cannot encode H.264 MP4
- delta payload size mismatch: expected ${expectedSize}, got $
- 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/a612adf87b371e99.
Report an issue: GitHub.