{"record":{"id":"261d7ab9c2bc69e4","repo":"remotion-dev/remotion","slug":"expected-stsc-box-in-trak-box","errorCode":null,"errorMessage":"Expected stsc box in trak box","messagePattern":"Expected stsc box in trak box","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/iso-base-media/collect-sample-positions-from-trak.ts","lineNumber":42,"sourceCode":"\t}\n\n\tconst stszBox = getStszBox(trakBox);\n\tconst stcoBox = getStcoBox(trakBox);\n\tconst stscBox = getStscBox(trakBox);\n\tconst stssBox = getStssBox(trakBox);\n\tconst sttsBox = getSttsBox(trakBox);\n\tconst cttsBox = getCttsBox(trakBox);\n\n\tif (!stszBox) {\n\t\tthrow new Error('Expected stsz box in trak box');\n\t}\n\n\tif (!stcoBox) {\n\t\tthrow new Error('Expected stco box in trak box');\n\t}\n\n\tif (!stscBox) {\n\t\tthrow new Error('Expected stsc box in trak box');\n\t}\n\n\tif (!sttsBox) {\n\t\tthrow new Error('Expected stts box in trak box');\n\t}\n\n\tif (!timescaleAndDuration) {\n\t\tthrow new Error('Expected timescale and duration in trak box');\n\t}\n\n\tconst samplePositions = getSamplePositions({\n\t\tstcoBox,\n\t\tstscBox,\n\t\tstszBox,\n\t\tstssBox,\n\t\tsttsBox,\n\t\tcttsBox,\n\t});","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/iso-base-media/collect-sample-positions-from-trak.ts#L24-L60","documentation":"Thrown by collectSamplePositionsFromTrak when a trak box lacks an stsc (Sample-to-Chunk) box. The stsc table maps each chunk to the number of samples it contains plus their default size delta, which is required to translate sample indices into byte ranges. ISO/IEC 14496-12 mandates stsc inside stbl for any sample table that is actually populated.","triggerScenarios":"A progressive MP4 trak whose stbl has no stsc child. Common with empty/placeholder traks, severely truncated files, or non-conformant muxers. Also reachable if the traversal that fetches stsc returns null because the box is present but parsed as a different type due to a size/encoding bug.","commonSituations":"Truncated downloads where the moov is at the head and the stbl got cut off. Files authored by research/specialized tools that write stsz/stco but skip stsc. Damaged files that survived a copy but lost a box boundary.","solutions":["Re-mux with `ffmpeg -i input.mp4 -c copy -movflags faststart fixed.mp4` to rebuild the sample tables.","Validate with `ffprobe` and reject the file upstream if the sample table is incomplete.","Wrap parse/seek calls in try/catch and degrade gracefully (skip seeking, treat as non-seekable stream).","If you produce the files, switch muxer settings to a conformant stbl layout."],"exampleFix":"// before\nconst positions = collectSamplePositionsFromTrak(trakBox);\n\n// after\nlet positions;\ntry {\n  positions = collectSamplePositionsFromTrak(trakBox);\n} catch (err) {\n  return { seekable: false, reason: 'incomplete-sample-table' };\n}","handlingStrategy":"try-catch","validationCode":"import {execFileSync} from 'node:child_process';\nfunction isSampleTableComplete(file: string): boolean {\n  try {\n    execFileSync('ffprobe', ['-v', 'error', '-count_frames', '-select_streams', 'v:0', '-show_entries', 'stream=nb_read_frames', '-of', 'csv', file], {encoding: 'utf8'});\n    return true;\n  } catch { return false; }\n}","typeGuard":"import type {TrakBox} from './trak/trak';\nimport {getStscBox} from './traversal';\nfunction trakHasStsc(trakBox: TrakBox): boolean {\n  return getStscBox(trakBox) !== null;\n}","tryCatchPattern":"try {\n  const positions = collectSamplePositionsFromTrak(trakBox);\n} catch (err) {\n  if (/Expected stsc box/i.test(String(err?.message))) {\n    return { seekable: false, reason: 'missing-stsc' };\n  }\n  throw err;\n}","preventionTips":["Treat any 'Expected <box> box in trak box' error as a corrupt-file signal and stop parsing that asset.","Standardize on a faststart re-mux step in your ingestion pipeline.","Surface a single, consistent 'unsupported file' message rather than raw box names to end users.","Log the failing file's hash so you can correlate recurring bad assets."],"tags":["mp4","isobmff","media-parser","corrupt-file","sample-table"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}