remotion-dev/remotion · error · Error
Expected WAVE, got
Error message
Expected WAVE, got ${fileType} What it means
parseHeader reads the 4 bytes after the RIFF size — the RIFF form-type — and requires ASCII 'WAVE'. Any other form-type means the file is a RIFF container but not a WAV (e.g. 'AVI ', 'RDIB', 'RMID'), so the WAV parser refuses it. This is the first integrity gate after the container sniffer routed the stream to the WAV parser.
Solutions
- Verify the file type: `file <path>` and ffprobe.
- Provide a real WAV, or use the correct parser for the actual container.
- Sniff the first 12 bytes yourself (RIFF....WAVE) before calling parseMedia().
- Use Mediabunny, which sniffs containers more robustly; try/catch.
Example fix
// before
await parseMedia({ src: maybeWav });
// after — sniff the RIFF/WAVE magic first
const buf = await readFirstNBytes(maybeWav, 12);
const isWav = buf[0] === 0x52 && buf.subarray(8, 12).toString() === 'WAVE';
if (!isWav) throw new Error('not a WAV');
await parseMedia({ src: maybeWav }); Defensive patterns
Strategy: validation
Validate before calling
// sniff the RIFF/WAVE magic before parsing
import { promises as fs } from 'fs';
const fd = await fs.open(path, 'r');
const buf = Buffer.alloc(12);
await fd.read(buf, 0, 12, 0);
await fd.close();
const isWav = buf.toString('ascii', 0, 4) === 'RIFF' && buf.toString('ascii', 8, 12) === 'WAVE';
if (!isWav) throw new Error('not a WAV file'); Type guard
const isWavFile = (head: Uint8Array) => head.length >= 12 && head[0] === 0x52 && head[1] === 0x49 && head[2] === 0x46 && head[3] === 0x46 && head[8] === 0x57 && head[9] === 0x41 && head[10] === 0x56 && head[11] === 0x45;
Try / catch
try {
await parseMedia({ src });
} catch (err) {
if (err instanceof Error && /Expected WAVE/.test(err.message)) {
// wrong container — route to the right parser or reject
} else throw err;
} Prevention
- Sniff the 12-byte RIFF/WAVE header before calling parseMedia().
- Don't trust file extensions; validate magic bytes.
- Use Mediabunny for more robust container detection.
When it happens
Trigger: A non-WAV RIFF file (AVI, RMI, RDIB) routed to the WAV parser, or a corrupted/truncated file whose form-type bytes are not 'WAVE'. Also triggers if a wrong file (non-RIFF) was force-routed to the WAV parser.
Common situations: Wrong file extension (AVI renamed .wav); truncated header; bytes flipped by a bad transfer; misidentified container.
Related errors
- Unknown WAV box type
- Error in Media Parser: End of parsing of
- Expected data box
- Expected fmt box
- Expected size 4 for fact box, got
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/072d43703a8dc65c.
Report an issue: GitHub.
Appendix: source
Thrown at packages/media-parser/src/containers/wav/parse-header.ts:13
import type {ParseResult} from '../../parse-result';
import type {ParserState} from '../../state/parser-state';
import type {WavHeader} from './types';
export const parseHeader = ({
state,
}: {
state: ParserState;
}): Promise<ParseResult> => {
const fileSize = state.iterator.getUint32Le();
const fileType = state.iterator.getByteString(4, false);
if (fileType !== 'WAVE') {
throw new Error(`Expected WAVE, got ${fileType}`);
}
const header: WavHeader = {
type: 'wav-header',
fileSize,
};
state.structure.getWavStructure().boxes.push(header);
return Promise.resolve(null);
};
View on GitHub (pinned to 78fe4bb3fd)