remotion-dev/remotion · error · Error
Value is null
Error message
Value is null
What it means
Thrown by parseM3uKeyValue() at parse-m3u-media-directive.ts:13 when processing attribute lists for directives like #EXT-X-MEDIA, #EXT-X-STREAM-INF, and #EXT-X-MAP. Each attribute token is split on the first '=' sign; if a token has no '=' (firstColon === -1), the value is null and the parser throws. HLS attribute lists require all entries to be KEY=VALUE pairs.
Source
Thrown at packages/media-parser/src/containers/m3u/parse-m3u-media-directive.ts:13
import {splitRespectingQuotes} from './parse-stream-inf';
import type {M3uMediaInfo} from './types';
export const parseM3uKeyValue = (str: string) => {
const quotes = splitRespectingQuotes(str);
const map: Record<string, string> = {};
for (const quote of quotes) {
const firstColon = quote.indexOf('=');
const key =
firstColon === -1 ? quote : (quote.slice(0, firstColon) as string);
const value = firstColon === -1 ? null : quote.slice(firstColon + 1);
if (value === null) {
throw new Error('Value is null');
}
const actualValue =
value?.startsWith('"') && value?.endsWith('"')
? value.slice(1, -1)
: value;
map[key] = actualValue;
}
return map;
};
export const parseM3uMediaDirective = (str: string): M3uMediaInfo => {
const map = parseM3uKeyValue(str);
return {
type: 'm3u-media-info',View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Verify all attributes in #EXT-X-MEDIA, #EXT-X-STREAM-INF, and #EXT-X-MAP use KEY=VALUE format with no bare keys
- Check for unescaped commas inside quoted attribute values that could create spurious bare tokens
- Regenerate the playlist with a compliant HLS packager
Example fix
// before — bare token 'AUTOSELECT' without a value #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac",AUTOSELECT,NAME="English" // after #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac",AUTOSELECT=YES,NAME="English"
Defensive patterns
Strategy: validation
Validate before calling
// Pre-fetch and validate that all attributes in EXT-* directives have KEY=VALUE format
const text = await (await fetch(url)).text();
for (const line of text.split('\n')) {
const trimmed = line.trim();
if (
trimmed.startsWith('#EXT-X-MEDIA:') ||
trimmed.startsWith('#EXT-X-STREAM-INF:') ||
trimmed.startsWith('#EXT-X-MAP:')
) {
const attrs = trimmed.slice(trimmed.indexOf(':') + 1);
// crude check: every comma-separated token should contain '='
for (const token of attrs.split(',')) {
if (token.trim() && !token.includes('=')) {
throw new Error(`Attribute token without '=': ${token}`);
}
}
}
} Try / catch
try {
await parseMedia({src: url});
} catch (e) {
if (e instanceof Error && e.message === 'Value is null') {
// a directive attribute list contains a bare token without '=' — fix the playlist
}
throw e;
} Prevention
- Verify all attributes in EXT-X-MEDIA, EXT-X-STREAM-INF, and EXT-X-MAP directives use KEY=VALUE format
- Check for unescaped commas inside quoted attribute values that could split tokens incorrectly
- Use a compliant packager to avoid malformed attribute lists
When it happens
Trigger: An attribute directive containing a bare token without an '=' sign — e.g. #EXT-X-MEDIA:TYPE=AUDIO,NOEQUALS,NAME="English" where 'NOEQUALS' lacks a '=value' suffix. Also fired by malformed comma-splitting where a value containing an unescaped comma creates a bare token.
Common situations: Malformed attribute list from a buggy encoder or packager; typo in a hand-edited playlist (missing '=value'); attribute value containing unescaped commas that confuse the quote-respecting splitter in splitRespectingQuotes().
Related errors
- EXT-X-MEDIA directive must have a value
- EXT-X-VERSION directive must have a value
- EXT-X-TARGETDURATION directive must have a value
- EXTINF has no value
- #EXT-X-PLAYLIST-TYPE. directive must have a value
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/d403c5efe8e26e88.
Report an issue: GitHub.