remotion-dev/remotion · error · Error
No video section defined
Error message
No video section defined
What it means
Thrown by getSeekingByteFromFragmentedMp4 in the fallback branch: after no seeking info matched and the current byte position is reportedly inside a media section, getCurrentMediaSection returns null. This means the mediaSections list does not actually contain the currentPosition even though isByteInMediaSection returned 'in-section' just above — an internal inconsistency, or the section list was mutated between the two checks.
Source
Thrown at packages/media-parser/src/containers/iso-base-media/get-seeking-byte-from-fragmented-mp4.ts:182
position: currentPosition,
mediaSections: info.mediaSections,
}) !== 'in-section'
) {
return {
type: 'valid-but-must-wait',
};
}
Log.trace(
logLevel,
'Fragmented MP4 - Inside the wrong video section, skipping to the end of the section',
);
const mediaSection = getCurrentMediaSection({
offset: currentPosition,
mediaSections: info.mediaSections,
});
if (!mediaSection) {
throw new Error('No video section defined');
}
return {
type: 'intermediary-seek',
byte: mediaSection.start + mediaSection.size,
};
};
View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Do not drive a single media-parser instance from multiple concurrent callers; serialize seek/parse operations.
- Capture a snapshot of mediaSections and pass the same array to both isByteInMediaSection and getCurrentMediaSection.
- Report a media-parser bug if this reproduces on a single-threaded call sequence — include the file and seek time.
- Retry the seek; transient if mediaSections is being populated incrementally.
Example fix
// before
await parser.seek(time);
// after
// Serialize seeks and capture section snapshot externally if driving manually
const sections = parser.getSeekingHints?.().mediaSections ?? [];
if (!sections.length) {
// wait for media sections to be discovered before seeking
await waitForFirstMdat();
}
await parser.seek(time); Defensive patterns
Strategy: retry
Validate before calling
// Ensure mediaSections is non-empty and stable before seeking
function hasMediaSections(sections: { start: number; size: number }[]): boolean {
return Array.isArray(sections) && sections.length > 0;
} Type guard
import type {MediaSection} from '../../state/video-section';
function currentPositionHasSection(pos: number, sections: MediaSection[]): boolean {
return sections.some((s) => pos >= s.start && pos < s.start + s.size);
} Try / catch
try {
await parser.seek(time);
} catch (err) {
if (/No video section defined/i.test(String(err?.message))) {
// mediaSections may still be populating; wait for the next mdat then retry
await waitForNextMdat();
return parser.seek(time);
}
throw err;
} Prevention
- Serialize seek operations on a single parser instance — do not call concurrently.
- Wait until at least one mdat/media section has been registered before seeking.
- Snapshot mediaSections once and reuse the same reference for both section checks.
- Report a bug if this reproduces under single-threaded usage.
When it happens
Trigger: Reached only when isByteInMediaSection reported the position is in a section but getCurrentMediaSection (which finds the specific section) returns null. Practically indicates a state mutation race: mediaSections changed between the two reads, or getCurrentMediaSection uses stricter bounds than isByteInMediaSection.
Common situations: Concurrent reads on a parser instance not designed for concurrency. mediaSections being pruned/shifted by another part of the parser between checks. A logic bug where the two helpers disagree on boundary conditions (e.g. inclusive vs exclusive end).
Related errors
- no video and no audio tracks
- No moov atom found
- No trak box found
- Expected tkhd box in trak box
- Expected stco box in trak box
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/4025d459ef636021.
Report an issue: GitHub.