{"record":{"id":"c1ac7cf6220d8ad8","repo":"remotion-dev/remotion","slug":"expected-box","errorCode":null,"errorMessage":"Expected box","messagePattern":"Expected box","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/iso-base-media/get-children.ts","lineNumber":32,"sourceCode":"\tsize: number;\n\titerator: BufferIterator;\n\tlogLevel: MediaParserLogLevel;\n\tonlyIfMoovAtomExpected: OnlyIfMoovAtomExpected | null;\n\tcontentLength: number;\n}): Promise<IsoBaseMediaBox[]> => {\n\tconst boxes: IsoBaseMediaBox[] = [];\n\tconst initial = iterator.counter.getOffset();\n\n\twhile (iterator.counter.getOffset() < size + initial) {\n\t\tconst parsed = await processBox({\n\t\t\titerator,\n\t\t\tlogLevel,\n\t\t\tonlyIfMoovAtomExpected,\n\t\t\tonlyIfMdatAtomExpected: null,\n\t\t\tcontentLength,\n\t\t});\n\t\tif (parsed.type !== 'box') {\n\t\t\tthrow new Error('Expected box');\n\t\t}\n\n\t\tboxes.push(parsed.box);\n\t}\n\n\tif (iterator.counter.getOffset() > size + initial) {\n\t\tthrow new Error(\n\t\t\t`read too many bytes - size: ${size}, read: ${iterator.counter.getOffset() - initial}. initial offset: ${initial}`,\n\t\t);\n\t}\n\n\treturn boxes;\n};\n","sourceCodeStart":14,"sourceCodeEnd":46,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/iso-base-media/get-children.ts#L14-L46","documentation":"Thrown by getIsoBaseMediaChildren when processBox returns a discriminated union value whose `type` is not 'box' (e.g. 'incomplete' or 'skip'). The container walker assumes each child parse within a parent box must complete as a fully parsed box, so any partial/incomplete result is treated as a structural failure. This generally means there were not enough bytes to finish the next child box even though the parent's declared size said more bytes should be present.","triggerScenarios":"A parent box (moov, trak, mdia, stbl, moof, etc.) declares a size larger than the actual payload, so the loop tries to read another child and processBox returns an incomplete result. Reachable on truncated downloads, mid-stream reads where the buffer does not yet contain the full box, or genuine corruption where size fields are wrong.","commonSituations":"Streaming parses where the network delivered a partial chunk and the parser was given a wrong content length. Files with manually edited size fields. Mid-transfer snapshots. Bugs in box size calculations from third-party muxers.","solutions":["Verify the source URL/bytes are complete: re-download and confirm Content-Length matches actual bytes.","If parsing a stream, ensure the iterator is fed until EOF before walking children, or use the streaming parse path that tolerates 'incomplete'.","Re-mux the file with ffmpeg to rebuild box size headers.","Catch the error at the parse boundary and treat the file as unparseable."],"exampleFix":"// before\nconst boxes = await getIsoBaseMediaChildren({ size, iterator, logLevel, onlyIfMoovAtomExpected, contentLength });\n\n// after\ntry {\n  const boxes = await getIsoBaseMediaChildren({ size, iterator, logLevel, onlyIfMoovAtomExpected, contentLength });\n} catch (err) {\n  throw new Error(`MP4 structure is truncated or corrupt: ${err instanceof Error ? err.message : err}`);\n}","handlingStrategy":"try-catch","validationCode":"// Ensure the buffer actually contains the full parent box before walking children\nfunction hasFullBox(buffer: Uint8Array, start: number, declaredSize: number): boolean {\n  return start + declaredSize <= buffer.byteLength;\n}","typeGuard":"import type {ProcessBoxResult} from './process-box';\nfunction isCompleteBoxResult(r: ProcessBoxResult): r is { type: 'box'; box: IsoBaseMediaBox } {\n  return r.type === 'box';\n}","tryCatchPattern":"try {\n  const boxes = await getIsoBaseMediaChildren({ size, iterator, logLevel, onlyIfMoovAtomExpected, contentLength });\n} catch (err) {\n  if (/^Expected box$/i.test(String(err?.message))) {\n    throw new Error('MP4 is truncated mid-box. Confirm the file is fully downloaded and not corrupt.');\n  }\n  throw err;\n}","preventionTips":["Confirm Content-Length and actual byte count match before parsing.","For streamed sources, wait until EOF or use a streaming-tolerant parse path that retries on 'incomplete'.","Catch structural errors at the public API boundary and present a single 'unsupported file' message.","Re-mux suspect files with ffmpeg before parsing."],"tags":["mp4","isobmff","media-parser","corrupt-file","streaming"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}