{"record":{"id":"dc803abe19e0d314","repo":"remotion-dev/remotion","slug":"no-video-section-defined-dc803a","errorCode":null,"errorMessage":"No video section defined","messagePattern":"No video section defined","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/iso-base-media/mdat/mdat.ts","lineNumber":33,"sourceCode":"import {\n\tmaySkipOverSamplesInTheMiddle,\n\tmaySkipVideoData,\n} from '../../../state/may-skip-video-data';\nimport type {ParserState} from '../../../state/parser-state';\nimport {getCurrentMediaSection} from '../../../state/video-section';\nimport {WEBCODECS_TIMESCALE} from '../../../webcodecs-timescale';\nimport {getMoovAtom} from '../get-moov-atom';\nimport {postprocessBytes} from './postprocess-bytes';\n\nexport const parseMdatSection = async (\n\tstate: ParserState,\n): Promise<Skip | FetchMoreData | null> => {\n\tconst mediaSection = getCurrentMediaSection({\n\t\toffset: state.iterator.counter.getOffset(),\n\t\tmediaSections: state.mediaSection.getMediaSections(),\n\t});\n\tif (!mediaSection) {\n\t\tthrow new Error('No video section defined');\n\t}\n\n\tconst endOfMdat = mediaSection.size + mediaSection.start;\n\n\t// don't need mdat at all, can skip\n\tif (maySkipVideoData({state})) {\n\t\tconst mfra = state.iso.mfra.getIfAlreadyLoaded();\n\n\t\tif (mfra) {\n\t\t\tconst lastMoof = getLastMoofBox(mfra);\n\t\t\tif (lastMoof && lastMoof > endOfMdat) {\n\t\t\t\tLog.verbose(state.logLevel, 'Skipping to last moof', lastMoof);\n\t\t\t\treturn makeSkip(lastMoof);\n\t\t\t}\n\t\t}\n\n\t\treturn makeSkip(endOfMdat);\n\t}","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/iso-base-media/mdat/mdat.ts#L15-L51","documentation":"Thrown at the start of parseMdatSection(). getCurrentMediaSection() returned null for the current iterator offset, i.e. the parser reached the sample-reading phase but no mdat (media data) box has been registered covering the current byte offset. The parser cannot locate the sample data region, so it aborts.","triggerScenarios":"parseMedia({src}) when the ISO structure lacks a registered mdat section at the read offset: e.g. a moov-only file with no mdat, a truncated/fragmented MP4 whose mdat boundaries were not added via mediaSectionState.addMediaSection(), or a stream where the mdat header was never observed (process-box.ts only registers an mdat when it reads the 'mdat' box type at lines 126-138).","commonSituations":"Moov-only or metadata-only MP4 files; fragmented MP4 segments missing the mdat wrapper; truncated downloads where the mdat header parsed but the data region math is off; seek scenarios into regions outside any known media section.","solutions":["Confirm the file actually contains sample data with ffprobe <file> (duration > 0 and streams present).","Re-mux the file to ensure a proper mdat: ffmpeg -i in.mp4 -c copy out.mp4.","If parsing a fragmented MP4 stream/segment, ensure you feed a complete init+media segment, not just the moov.","Avoid manual seeking past known media sections; if using a controller/seekingHints, keep seeks inside the file's media range."],"exampleFix":"// before\nawait parseMedia({src: maybeMoovOnlyMp4, reader: nodeReader, onVideoTrack: () => {}});\n\n// after\ntry {\n  await parseMedia({src: maybeMoovOnlyMp4, reader: nodeReader, onVideoTrack: () => {}});\n} catch (err) {\n  if (err instanceof Error && /No video section defined/.test(err.message)) {\n    console.warn('File has no mdat/sample data region; nothing to decode');\n  } else throw err;\n}","handlingStrategy":"try-catch","validationCode":"// Confirm the file actually contains sample data (duration > 0) before parsing:\n//   ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 in.mp4\nimport {execFileSync} from 'node:child_process';\nfunction hasMediaData(file: string): boolean {\n  try {\n    const out = execFileSync('ffprobe',\n      ['-v','error','-show_entries','format=duration','-of','default=nw=1:nk=1', file],\n      {encoding: 'utf8'});\n    const d = Number(out.trim());\n    return Number.isFinite(d) && d > 0;\n  } catch { return false; }\n}","typeGuard":"// src is a URL/File/Uint8Array; media-section presence is internal parser\n// state, not something the caller can narrow on.\n// => typeGuard: null","tryCatchPattern":"try {\n  await parseMedia({src, reader: nodeReader, onVideoTrack: () => {}});\n} catch (err) {\n  if (err instanceof Error && /No video section defined/.test(err.message)) {\n    // no mdat/sample-data region: nothing to decode\n  } else {\n    throw err;\n  }\n}","preventionTips":["Validate files report a non-zero duration with ffprobe before parsing.","Feed complete init+media segments for fragmented MP4, not moov-only fragments.","Keep seeks within known media regions when using a controller.","Migrate to @remotion/mediabunny (parseMedia is deprecated)."],"tags":["mp4","iso-base-media","media-parser","mdat","corrupt-file","fragmented-mp4","truncated"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}