{"record":{"id":"12ecb11a0cad28e8","repo":"remotion-dev/remotion","slug":"has-no-bytes","errorCode":null,"errorMessage":"has no bytes","messagePattern":"has no bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/webm/segments.ts","lineNumber":35,"sourceCode":"export type MatroskaSegment = PossibleEbml;\n\nexport type OnTrackEntrySegment = (trackEntry: TrackEntry) => void;\n\nexport const expectSegment = async ({\n\tstatesForProcessing,\n\tisInsideSegment,\n\titerator,\n\tlogLevel,\n\tmediaSectionState,\n}: {\n\titerator: BufferIterator;\n\tlogLevel: MediaParserLogLevel;\n\tstatesForProcessing: WebmRequiredStatesForProcessing | null;\n\tisInsideSegment: SegmentSection | null;\n\tmediaSectionState: MediaSectionState | null;\n}): Promise<MatroskaSegment | null> => {\n\tif (iterator.bytesRemaining() === 0) {\n\t\tthrow new Error('has no bytes');\n\t}\n\n\tconst offset = iterator.counter.getOffset();\n\tconst {returnToCheckpoint} = iterator.startCheckpoint();\n\tconst segmentId = iterator.getMatroskaSegmentId();\n\n\tif (segmentId === null) {\n\t\treturnToCheckpoint();\n\t\treturn null;\n\t}\n\n\tconst offsetBeforeVInt = iterator.counter.getOffset();\n\tconst size = iterator.getVint();\n\tconst offsetAfterVInt = iterator.counter.getOffset();\n\n\tif (size === null) {\n\t\treturnToCheckpoint();\n\t\treturn null;","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/webm/segments.ts#L17-L53","documentation":"expectSegment throws 'has no bytes' if iterator.bytesRemaining()===0 at entry. The function is called repeatedly by parseWebm to read the next top-level element; reaching it with zero bytes means the continuation loop was not stopped at end-of-stream. The branch is a defensive guard for a state-machine edge.","triggerScenarios":"The parser is asked to read another element after the stream is fully consumed - typically a bug in the parse loop's termination condition, or a reader that signals EOF late. Also reachable if a Segment declared an unknown size but the underlying reader hit EOF and the loop did not break.","commonSituations":"Custom readers that misreport bytesRemaining, or malformed files where the Segment size is unknown (live-streamed) and EOF handling races with the loop.","solutions":["If using a custom reader, ensure bytesRemaining() returns 0 exactly when EOF is reached and that parseMedia's loop observes it.","Re-mux the file to give the Segment a concrete size.","Use the built-in webReader or fetchReader with a complete Blob instead.","Try Mediabunny."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// For a custom reader, guarantee bytesRemaining>0 before each expectSegment call.\n// At the caller level, prefer a fully-buffered source so the parser's EOF loop works.\nconst bytes = new Uint8Array(await (await fetch(url)).arrayBuffer());\nif (bytes.byteLength === 0) throw new Error('empty media source');\nawait parseMedia({src: bytes});","typeGuard":null,"tryCatchPattern":"try {\n  await parseMedia({src});\n} catch (err) {\n  if (err instanceof Error && err.message === 'has no bytes') {\n    throw new Error('Parser asked to read past EOF; use a complete, buffered source.', {cause: err});\n  }\n  throw err;\n}","preventionTips":["Pass a complete Uint8Array/Blob rather than a streaming reader when possible.","On custom readers, ensure bytesRemaining() is accurate and EOF is signalled cleanly.","Give the Segment a concrete size by re-muxing live-streamed sources."],"tags":["webm","matroska","media-parser","reader","eof","internal-invariant"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}