remotion-dev/remotion · error · Error

Expected length is null

Error message

Expected length is null

What it means

Thrown by processAudio at process-audio.ts:70 when readAdtsHeader returns null (no parseable ADTS header) for the buffered audio bytes. The library expects AAC streams to carry an ADTS framing; without it, the frame length cannot be determined.

Source

Thrown at packages/media-parser/src/containers/transport-stream/process-audio.ts:70

	logLevel: MediaParserLogLevel;
	onAudioTrack: MediaParserOnAudioTrack | null;
	onVideoTrack: MediaParserOnVideoTrack | null;
	transportStream: TransportStreamState;
	offset: number;
	makeSamplesStartAtZero: boolean;
	avcState: AvcState;
}): Promise<void> => {
	const {streamBuffers, nextPesHeaderStore: nextPesHeader} = transportStream;
	const streamBuffer = streamBuffers.get(transportStreamEntry.pid);
	if (!streamBuffer) {
		throw new Error('Stream buffer not found');
	}

	const expectedLength =
		readAdtsHeader(streamBuffer.getBuffer())?.frameLength ?? null;

	if (expectedLength === null) {
		throw new Error('Expected length is null');
	}

	if (expectedLength > streamBuffer.getBuffer().length) {
		throw new Error('Expected length is greater than stream buffer length');
	}

	await processStreamBuffer({
		streamBuffer: makeTransportStreamPacketBuffer({
			buffers: streamBuffer.getBuffer().slice(0, expectedLength),
			offset,
			pesHeader: streamBuffer.pesHeader,
		}),
		programId: transportStreamEntry.pid,
		structure,
		sampleCallbacks,
		logLevel,
		onAudioTrack,
		onVideoTrack,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Re-encode audio as plain ADTS-AAC: ffmpeg -i in.ts -c:a aac -f adts out.aac, then re-mux.
  2. Verify the audio codec with ffprobe before parsing.
  3. Filter the stream to only supported codecs before passing to @remotion/media-parser.
  4. File a feature request if you need MP2/AC-3/LATM support.
Defensive patterns

Strategy: validation

Validate before calling

// Verify audio codec is AAC/ADTS before parsing
import {execSync} from 'node:child_process';
function isAdtsAac(src: string): boolean {
  try {
    const out = execSync(`ffprobe -v error -select_streams a -show_entries stream=codec_name -of csv=p=0 "${src}"`).toString().trim();
    return out === 'aac';
  } catch { return false; }
}

Try / catch

try { await parseMedia({src}); }
catch (e) {
  if (e instanceof Error && e.message === 'Expected length is null') {
    // re-encode audio as ADTS-AAC
    await runFfmpeg(['-i', src, '-c:v', 'copy', '-c:a', 'aac', '-f', 'mpegts', out]);
    await parseMedia({src: out});
  } else throw e;
}

Prevention

When it happens

Trigger: processAudio calls readAdtsHeader(streamBuffer.getBuffer()) and checks for a null result. Triggered when the audio PID is not actually AAC/ADTS (e.g. MP2/MP3, AC-3, or raw AAC LATM), when the buffer is too short to contain a full ADTS header (7 bytes), or when the bytes are corrupted.

Common situations: Stream declared as stream_type=15 (AAC) but actually carrying another codec; partial packets where ADTS framing is split; LATM/LOAS wrapped AAC; private-stream audio routed through the AAC path.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/ba37b0d9b0d7ad28. Report an issue: GitHub.