{"record":{"id":"c41a34a975d63991","repo":"remotion-dev/remotion","slug":"invalid-mpeg-layer","errorCode":null,"errorMessage":"Invalid MPEG layer","messagePattern":"Invalid MPEG layer","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/mp3/samples-per-mpeg-file.ts","lineNumber":32,"sourceCode":"\t\t\treturn 1152;\n\t\t}\n\t}\n\n\tif (mpegVersion === 2) {\n\t\tif (layer === 1) {\n\t\t\treturn 384;\n\t\t}\n\n\t\tif (layer === 2) {\n\t\t\treturn 1152;\n\t\t}\n\n\t\tif (layer === 3) {\n\t\t\treturn 576;\n\t\t}\n\t}\n\n\tthrow new Error('Invalid MPEG layer');\n};\n","sourceCodeStart":14,"sourceCodeEnd":34,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/mp3/samples-per-mpeg-file.ts#L14-L34","documentation":"Thrown by getSamplesPerMpegFrame() (samples-per-mpeg-file.ts) when the (mpegVersion, layer) pair does not match any of the supported branches. Valid MPEG audio layers are 1, 2, 3 for MPEG-1 and MPEG-2; any other combination (e.g. layer === 0, which is 'reserved' in the spec) falls through to the throw.","triggerScenarios":"An MP3 frame whose layer field is the reserved value 0b00, or an mpegVersion outside the handled 1/2 set. Usually a corrupt frame header or non-MPEG data being parsed as MPEG.","commonSituations":"Corrupt/truncated MP3; random bytes misidentified as MP3; a frame header where bit-flips changed the layer field to the reserved value.","solutions":["Validate the frame header's layer bits before computing samples-per-frame: layer must be 1, 2, or 3.","Re-encode the source audio to a clean MP3: ffmpeg -i in.mp3 -c:a libmp3lame -b:a 192k out.mp3","If parsing untrusted input, wrap the parse call in try/catch and skip the offending frame."],"exampleFix":"// before\nconst spf = getSamplesPerMpegFrame({layer, mpegVersion});\n\n// after\nif (layer !== 1 && layer !== 2 && layer !== 3) {\n  throw new Error(`Skipping frame with reserved MPEG layer ${layer}`);\n}\nconst spf = getSamplesPerMpegFrame({layer, mpegVersion});","handlingStrategy":"validation","validationCode":"// Validate MPEG layer before computing samples-per-frame.\nfunction isValidMpegLayer(layer: number): boolean {\n  return layer === 1 || layer === 2 || layer === 3;\n}\nif (!isValidMpegLayer(layer)) {\n  throw new Error(`Reserved/invalid MPEG layer ${layer} — corrupt frame`);\n}","typeGuard":"function isValidMpegLayer(layer: number): layer is 1 | 2 | 3 {\n  return layer === 1 || layer === 2 || layer === 3;\n}","tryCatchPattern":"try {\n  const spf = getSamplesPerMpegFrame({layer, mpegVersion});\n} catch (err) {\n  if (err instanceof Error && err.message === 'Invalid MPEG layer') {\n    // skip this frame; do not abort the whole parse\n  } else throw err;\n}","preventionTips":["Decode and validate the MPEG header's layer field before any layer-dependent call.","Treat layer === 0 as corrupt and skip the frame.","Reject files whose first frame has an invalid layer."],"tags":["mp3","mpeg-layer","corrupt-frame","media-parser"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}