{"record":{"id":"f06d758199a98332","repo":"remotion-dev/remotion","slug":"ext-x-media-directive-must-have-a-value","errorCode":null,"errorMessage":"EXT-X-MEDIA directive must have a value","messagePattern":"EXT-X-MEDIA directive must have a value","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/m3u/parse-directive.ts","lineNumber":32,"sourceCode":"\t\tif (!value) {\n\t\t\tthrow new Error('EXT-X-VERSION directive must have a value');\n\t\t}\n\n\t\treturn {\n\t\t\ttype: 'm3u-version',\n\t\t\tversion: value,\n\t\t};\n\t}\n\n\tif (directive === '#EXT-X-INDEPENDENT-SEGMENTS') {\n\t\treturn {\n\t\t\ttype: 'm3u-independent-segments',\n\t\t};\n\t}\n\n\tif (directive === '#EXT-X-MEDIA') {\n\t\tif (!value) {\n\t\t\tthrow new Error('EXT-X-MEDIA directive must have a value');\n\t\t}\n\n\t\tconst parsed = parseM3uMediaDirective(value);\n\n\t\treturn parsed;\n\t}\n\n\tif (directive === '#EXT-X-TARGETDURATION') {\n\t\tif (!value) {\n\t\t\tthrow new Error('EXT-X-TARGETDURATION directive must have a value');\n\t\t}\n\n\t\treturn {\n\t\t\ttype: 'm3u-target-duration',\n\t\t\tduration: parseFloat(value),\n\t\t};\n\t}\n","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/m3u/parse-directive.ts#L14-L50","documentation":"Thrown by parseM3uDirective() at parse-directive.ts:32 when a line matches #EXT-X-MEDIA but has no attribute value after the colon. The #EXT-X-MEDIA directive declares audio, subtitle, or closed-caption renditions and requires attributes (TYPE, GROUP-ID, NAME, etc.) to describe the rendition. The parser delegates to parseM3uMediaDirective which needs a non-null value string.","triggerScenarios":"A playlist line '#EXT-X-MEDIA' with no colon or '#EXT-X-MEDIA:' with empty attributes — no TYPE=, GROUP-ID=, NAME= key-value pairs.","commonSituations":"Corrupted audio or subtitle track declaration in a master playlist; encoder bug producing incomplete EXT-X-MEDIA lines; hand-edited playlist where attributes were removed.","solutions":["Ensure #EXT-X-MEDIA carries full attributes, e.g. #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"aac\",NAME=\"English\",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE=\"en\",URI=\"audio.m3u8\"","Regenerate the playlist with a compliant packager","Remove the malformed EXT-X-MEDIA line if the rendition is not needed"],"exampleFix":"// before\n#EXT-X-MEDIA:\n\n// after\n#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"aac\",NAME=\"English\",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE=\"en\",URI=\"audio_en.m3u8\"","handlingStrategy":"validation","validationCode":"// Pre-fetch and check EXT-X-MEDIA lines have attributes\nconst text = await (await fetch(url)).text();\nfor (const line of text.split('\\n')) {\n  const trimmed = line.trim();\n  if (trimmed.startsWith('#EXT-X-MEDIA')) {\n    const colonIdx = trimmed.indexOf(':');\n    if (colonIdx === -1 || !trimmed.slice(colonIdx + 1).trim()) {\n      throw new Error('#EXT-X-MEDIA is missing its attributes');\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await parseMedia({src: url});\n} catch (e) {\n  if (e instanceof Error && e.message.includes('EXT-X-MEDIA')) {\n    // fix the malformed EXT-X-MEDIA line in the source playlist\n  }\n  throw e;\n}","preventionTips":["Validate audio/subtitle rendition declarations in generated playlists","Use a compliant packager to produce well-formed EXT-X-MEDIA attributes"],"tags":["hls","m3u8","directive","ext-x-media","malformed","audio-tracks"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}