{"record":{"id":"3cafb738a08c76fc","repo":"subhra74/xdm","slug":"no-period-found","errorCode":null,"errorMessage":"No period found!","messagePattern":"No period found!","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/XDM/XDM.Core/MediaParser/Dash/MpdParser.cs","lineNumber":51,"sourceCode":"                throw new Exception(\"Missing MPD start tag: \" + xmldoc.DocumentElement.Name);\r\n            if (xmldoc.DocumentElement.Attributes[\"type\"]?.Value == \"dynamic\")\r\n                throw new Exception(\"Manifest type dynamic is not supported\");\r\n            if (xmldoc.DocumentElement.SelectSingleNode(\"descendant::ContentProtection\") != null)\r\n                throw new Exception(\"Encrypted manifest\");\r\n\r\n            var mediaList = new List<IList<KeyValuePair<Representation?, Representation?>>>();\r\n\r\n            var mediaPresentationDuration =\r\n                DashUtil.ParseXsDuration(xmldoc.DocumentElement.Attributes[\"mediaPresentationDuration\"]?.Value ?? \"0\");\r\n            var baseUrl = new Uri(playlistUrl);\r\n            var baseUrlNodeRoot = xmldoc.DocumentElement.SelectSingleNode(\"child::BaseURL\");\r\n            if (baseUrlNodeRoot != null)\r\n            {\r\n                baseUrl = UrlResolver.Resolve(baseUrl, baseUrlNodeRoot.InnerText);\r\n            }\r\n\r\n            var periods = xmldoc.DocumentElement.SelectNodes(\"child::Period\");\r\n            if (periods == null || periods.Count < 1) throw new Exception(\"No period found!\");\r\n            if (periods.Count > 1)\r\n            {\r\n                var periodDurations = CalculatePeriodDurationsIfMissing(periods, mediaPresentationDuration);\r\n                for (var i = 0; i < periods.Count; i++)\r\n                {\r\n                    var period = periods[i];\r\n                    mediaList.Add(ParsePeriod(period, baseUrl, periodDurations[i]));\r\n                }\r\n            }\r\n            else if (periods.Count == 1)\r\n            {\r\n                mediaList.Add(ParsePeriod(periods[0], baseUrl, mediaPresentationDuration));\r\n            }\r\n\r\n            return mediaList;\r\n        }\r\n\r\n        private static IList<KeyValuePair<Representation?, Representation?>> ParsePeriod(XmlNode period, Uri baseUrl, long mediaPresentationDuration)\r","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/subhra74/xdm/blob/1ca5a25aae007826c859c81bea494e7c102e1242/app/XDM/XDM.Core/MediaParser/Dash/MpdParser.cs#L33-L69","documentation":"A valid MPD must contain at least one <Period> child of the root MPD element. After resolving the base URL, Parse selects child::Period and throws this error when the node list is null or empty, since the rest of the parser (representations, segments) is built from periods.","triggerScenarios":"Parsing an XML document whose root is MPD but contains no <Period> children — e.g. a minimal/invalid manifest, a manifest where periods are namespaced (parser runs with Namespaces=false, so prefixed elements like <ns:Period> won't match), or a truncated download.","commonSituations":"Manifest truncated by a proxy or interrupted download; unusual manifest where Period elements carry a namespace prefix so child::Period finds nothing; hand-crafted or vendor-specific MPD that omits Period; wrong XML selected due to no-namespace parsing mode.","solutions":["Open the MPD and verify it contains at least one <Period> element directly under <MPD>.","Re-download the manifest — a partial response can omit periods; compare byte size/hash with the server's.","If the manifest uses namespace prefixes for Period, strip or normalize namespaces before parsing.","Verify you are parsing the MPD itself, not a wrapper document or an error page that happens to have an MPD root."],"exampleFix":"// before\nvar media = MpdParser.Parse(mpdUrl, null);\n\n// after\nvar xml = DownloadManifest(mpdUrl);\nif (!xml.Contains(\"<Period\"))\n    throw new Exception(\"Manifest has no Period elements; not a usable DASH VOD\");\nvar media = MpdParser.Parse(mpdUrl, null);","handlingStrategy":"validation","validationCode":"var body = await http.GetStringAsync(mpdUrl);\nif (!body.Contains(\"<Period\"))\n    throw new Exception(\"MPD has no Period elements\");","typeGuard":null,"tryCatchPattern":"try { return MpdParser.Parse(url, null); }\ncatch (Exception ex) when (ex.Message == \"No period found!\")\n{ Log.Warn(\"MPD without periods (truncated or namespaced manifest): {0}\", url); throw; }","preventionTips":["Verify the manifest fully downloaded (Content-Length vs actual size)","Check for namespace prefixes on Period elements since the parser disables namespaces","Validate manifests with the DASH-IF conformance tool in CI"],"tags":["dash","xml","manifest-parsing","empty-result"],"backgroundTag":"empty-result-set","analyzedSha":"1ca5a25aae007826c859c81bea494e7c102e1242","analyzedAt":"2026-09-13T20:37:40.968Z","contentChangedAt":"2026-09-13T20:37:40.968Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}