{"record":{"id":"648dea5208cfb773","repo":"remotion-dev/remotion","slug":"no-main-segment","errorCode":null,"errorMessage":"No main segment","messagePattern":"No main segment","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/webm/get-ready-tracks.ts","lineNumber":26,"sourceCode":"} from './make-track';\nimport {getMainSegment, getTracksSegment} from './traversal';\n\nexport type ResolvedAndUnresolvedTracks = {\n\tresolved: MediaParserTrack[];\n\tmissingInfo: MediaParserTrack[];\n};\n\nexport const getTracksFromMatroska = ({\n\tstructureState,\n\twebmState,\n}: {\n\tstructureState: StructureState;\n\twebmState: WebmState;\n}): ResolvedAndUnresolvedTracks => {\n\tconst structure = structureState.getMatroskaStructure();\n\tconst mainSegment = getMainSegment(structure.boxes);\n\tif (!mainSegment) {\n\t\tthrow new Error('No main segment');\n\t}\n\n\tconst tracksSegment = getTracksSegment(mainSegment);\n\n\tif (!tracksSegment) {\n\t\tthrow new Error('No tracks segment');\n\t}\n\n\tconst resolvedTracks: MediaParserTrack[] = [];\n\tconst missingInfo: MediaParserTrack[] = [];\n\n\tfor (const trackEntrySegment of tracksSegment.value) {\n\t\tif (trackEntrySegment.type === 'Crc32') {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (trackEntrySegment.type !== 'TrackEntry') {\n\t\t\tthrow new Error('Expected track entry segment');","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/webm/get-ready-tracks.ts#L8-L44","documentation":"getTracksFromMatroska walks the parsed EBML box list looking for a top-level Matroska Segment element (ID 0x18538067). If getMainSegment returns null it throws 'No main segment' — the file is not a complete/valid Matroska or WebM, or the Segment has not yet been parsed. This runs while resolving tracks.","triggerScenarios":"parseMedia() on a .mkv/.webm that has no top-level Segment: truncated/empty file, a header-only stream, a live stream parsed before the Segment arrived, or a non-Matroska file misrouted to the WebM parser.","commonSituations":"Truncated download; live stream read too early; corrupted EBML; wrong container sniff; empty file.","solutions":["Verify with ffprobe that the file is a valid Matroska/WebM with a Segment.","Re-download or re-mux: ffmpeg -i in.mkv -c copy out.mkv.","Sniff the EBML magic (0x1A45DFA3) before parsing.","Use Mediabunny; try/catch parseMedia()."],"exampleFix":"# validate then re-mux\nffprobe -v error in.mkv && ffmpeg -i in.mkv -c copy out.mkv\n\nawait parseMedia({ src: 'out.mkv' });","handlingStrategy":"validation","validationCode":"// sniff the EBML magic before parsing a Matroska/WebM file\nimport { promises as fs } from 'fs';\nconst fd = await fs.open(path, 'r');\nconst buf = Buffer.alloc(4);\nawait fd.read(buf, 0, 4, 0);\nawait fd.close();\n// EBML magic = 0x1A 0x45 0xDF 0xA3\nconst isMatroska = buf[0] === 0x1a && buf[1] === 0x45 && buf[2] === 0xdf && buf[3] === 0xa3;\nif (!isMatroska) throw new Error('not a Matroska/WebM file');","typeGuard":"const isMatroska = (head: Uint8Array) =>\n  head.length >= 4 && head[0] === 0x1a && head[1] === 0x45 && head[2] === 0xdf && head[3] === 0xa3;","tryCatchPattern":"try {\n  await parseMedia({ src });\n} catch (err) {\n  if (err instanceof Error && /No main segment/.test(err.message)) {\n    // truncated/invalid Matroska — re-mux or skip\n  } else throw err;\n}","preventionTips":["Sniff the EBML magic before parsing.","Validate MKV/WebM with ffprobe (it must report a Segment).","Don't parse live/truncated streams expecting a full Segment.","Use Mediabunny."],"tags":["webm","matroska","media-parser","corrupt-file","container"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}