remotion-dev/remotion · error
Expected mvhd-box
Error message
Expected mvhd-box
What it means
Thrown by getDuration() as a defensive type check after getMvhdBox(moovBox) returns a non-null value whose type is not 'mvhd-box'. In practice the moov box is expected to contain exactly one well-formed movie header; reaching this throw means the box parser produced a node of the wrong type, indicating corrupt data or an internal invariant violation rather than normal user input.
Source
Thrown at packages/media-parser/src/get-duration.ts:93
const moofBoxes = getMoofBoxes(structure.boxes);
const mfra = parserState.iso.mfra.getIfAlreadyLoaded();
const tfraBoxes = deduplicateTfraBoxesByOffset([
...(mfra ? getTfraBoxesFromMfraBoxChildren(mfra) : []),
...getTfraBoxes(structure.boxes),
]);
if (!areSamplesComplete({moofBoxes, tfraBoxes})) {
return null;
}
const mvhdBox = getMvhdBox(moovBox);
if (!mvhdBox) {
return null;
}
if (mvhdBox.type !== 'mvhd-box') {
throw new Error('Expected mvhd-box');
}
if (mvhdBox.durationInSeconds > 0) {
return mvhdBox.durationInSeconds;
}
const tracks = getTracks(parserState, true);
const allSamples = tracks.map((t) => {
const {originalTimescale: ts} = t;
const trakBox = getTrakBoxByTrackId(moovBox, t.trackId);
if (!trakBox) {
return null;
}
const {samplePositions, isComplete} = getSamplePositionsFromTrack({View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Re-fetch or re-mux the source file; a conformant MP4 should not reach this branch.
- Wrap duration parsing in try/catch and fall back to a sample-based duration calculation or null duration.
- Report the file to the library maintainers with the structure dump, since this guard usually signals an internal invariant break.
Example fix
// before
const duration = getDuration(parserState);
// after
let duration;
try {
duration = getDuration(parserState);
} catch (err) {
console.warn('Could not read mvhd duration', err);
duration = null;
} Defensive patterns
Strategy: try-catch
Validate before calling
const mvhd = getMvhdBox(moovBox);
if (mvhd && mvhd.type === 'mvhd-box' && mvhd.durationInSeconds > 0) { /* safe */ } Type guard
const isMvhdBox = (b): b is MvhdBox => b?.type === 'mvhd-box';
Try / catch
try { getDuration(parserState); } catch (e) { if (e.message === 'Expected mvhd-box') { /* corrupt moov, fall back to null duration */ } else throw e; } Prevention
- Wrap duration reads in try/catch.
- Re-mux or re-fetch corrupt MP4 files.
- Report internal-invariant breaks to maintainers.
When it happens
Trigger: A malformed MP4 where the moov contains a box that getMvhdBox matched but is not actually typed mvhd-box. Extremely rare; usually points to a parser bug or bit-flipped box header.
Common situations: Processing damaged MP4 files. Encountering edge cases in fragmented MP4s where the moov is reconstructed from segments. After partial writes or truncated downloads that nonetheless yielded a box.
Related errors
- expected 0 bytes ${bytesRemaining}
- Movie timescale is not set
- Expected stsz box in trak box
- Expected stco box in trak box
- Expected stsc box in trak box
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/8dd1b5081a391761.
Report an issue: GitHub.