{"record":{"id":"39beb8b04c20138b","repo":"remotion-dev/remotion","slug":"ext-x-map-directive-must-have-a-uri","errorCode":null,"errorMessage":"EXT-X-MAP directive must have a URI","messagePattern":"EXT-X-MAP directive must have a URI","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/m3u/parse-directive.ts","lineNumber":136,"sourceCode":"\tif (directive === '#EXT-X-ALLOW-CACHE') {\n\t\tif (!value) {\n\t\t\tthrow new Error('#EXT-X-ALLOW-CACHE directive must have a value');\n\t\t}\n\n\t\treturn {\n\t\t\ttype: 'm3u-allow-cache',\n\t\t\tallowsCache: value === 'YES',\n\t\t};\n\t}\n\n\tif (directive === '#EXT-X-MAP') {\n\t\tif (!value) {\n\t\t\tthrow new Error('#EXT-X-MAP directive must have a value');\n\t\t}\n\n\t\tconst p = parseM3uKeyValue(value);\n\t\tif (!p.URI) {\n\t\t\tthrow new Error('EXT-X-MAP directive must have a URI');\n\t\t}\n\n\t\treturn {\n\t\t\ttype: 'm3u-map',\n\t\t\tvalue: p.URI,\n\t\t};\n\t}\n\n\tif (directive === '#EXT-X-PROGRAM-DATE-TIME') {\n\t\tif (!value) {\n\t\t\tthrow new Error('#EXT-X-PROGRAM-DATE-TIME directive must have a value');\n\t\t}\n\n\t\t// Store the raw ISO 8601 date-time string without validation.\n\t\t// This directive associates media segments with absolute dates but\n\t\t// doesn't affect parsing of tracks, dimensions, or other metadata.\n\t\treturn {\n\t\t\ttype: 'm3u-program-date-time',","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/m3u/parse-directive.ts#L118-L154","documentation":"Thrown by parseM3uDirective() at parse-directive.ts:136 when #EXT-X-MAP has attribute text but parseM3uKeyValue() did not produce a URI key. Per RFC 8216 section 4.3.2.5 the URI attribute is REQUIRED on #EXT-X-MAP because it tells the client where to fetch the initialization segment. The parser checks p.URI after parsing the key-value pairs.","triggerScenarios":"A #EXT-X-MAP line that has attributes but omits the URI key — e.g. #EXT-X-MAP:BYTERANGE=\"4500@600\" without URI=\"...\".","commonSituations":"Encoder or packager bug producing an EXT-X-MAP with only BYTERANGE but no URI; hand-edited playlist where the URI attribute was accidentally deleted; malformed init segment declaration.","solutions":["Ensure #EXT-X-MAP includes URI=\"...\": #EXT-X-MAP:URI=\"init.mp4\",BYTERANGE=\"4500@600\"","Regenerate the playlist with a compliant HLS packager","Check the init segment URL is valid and reachable"],"exampleFix":"// before\n#EXT-X-MAP:BYTERANGE=\"4500@600\"\n\n// after\n#EXT-X-MAP:URI=\"init.mp4\",BYTERANGE=\"4500@600\"","handlingStrategy":"validation","validationCode":"// Pre-fetch and check EXT-X-MAP has a URI attribute\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-MAP')) {\n    if (!/URI=/.test(trimmed)) {\n      throw new Error('#EXT-X-MAP is missing the required URI attribute');\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await parseMedia({src: url});\n} catch (e) {\n  if (e instanceof Error && e.message === 'EXT-X-MAP directive must have a URI') {\n    // add URI=\"...\" to the EXT-X-MAP directive\n  }\n  throw e;\n}","preventionTips":["Always include URI=\"...\" in #EXT-X-MAP directives — it is required by RFC 8216","Validate CMAF/fMP4 playlists with an HLS conformance checker"],"tags":["hls","m3u8","directive","ext-x-map","uri","malformed","initialization-segment"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}