{"record":{"id":"663af2f15f5af621","repo":"iawia002/lux","slug":"could-not-read-page-data","errorCode":null,"errorMessage":"Could not read page data","messagePattern":"Could not read page data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"extractors/odysee/odysee.go","lineNumber":61,"sourceCode":"\tswitch res.Header.Get(\"Content-Encoding\") {\n\tcase \"gzip\":\n\t\treader, _ = gzip.NewReader(res.Body)\n\tcase \"deflate\":\n\t\treader = flate.NewReader(res.Body)\n\tdefault:\n\t\treader = res.Body\n\t}\n\tdefer reader.Close() // nolint\n\n\tb, err := io.ReadAll(reader)\n\tif err != nil {\n\t\treturn nil, errors.WithStack(err)\n\t}\n\n\tregScript := regexp.MustCompile(`(?im)\\<script type=\"application\\/ld\\+json\"\\>([\\s\\S]*)[\\n?]<\\/script>`)\n\tmatchPayload := regScript.FindSubmatch(b)\n\tif len(matchPayload) < 2 {\n\t\treturn nil, errors.New(\"Could not read page data\")\n\t}\n\n\tvar resData odyseePayload\n\tif err := json.Unmarshal(matchPayload[1], &resData); err != nil {\n\t\treturn nil, errors.WithStack(err)\n\t}\n\n\tstreams := make(map[string]*extractors.Stream, 1)\n\tsize, err := request.Size(resData.ContentURL, u)\n\tif err != nil {\n\t\treturn nil, errors.WithStack(err)\n\t}\n\n\tstreams[\"Default\"] = &extractors.Stream{\n\t\tParts: []*extractors.Part{\n\t\t\t{\n\t\t\t\tURL:  resData.ContentURL,\n\t\t\t\tSize: size,","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/iawia002/lux/blob/dd00f6d258d80b6684a0b9402d7124e5c18ef42f/extractors/odysee/odysee.go#L43-L79","documentation":"Thrown by the Odysee extractor when the fetched claim page's bytes do not contain a <script type=\"application/ld+json\">...</script> block matching the regex. The LD-JSON payload is how the extractor finds ContentURL, so without it nothing can be extracted. The page downloaded fine but its structure is not what the extractor expects.","triggerScenarios":"Calling Extract on an Odysee claim URL where the server returns an error page, an anti-bot/consent interstitial, or a redesigned page whose ld+json script tag no longer matches `(?im)<script type=\"application\\/ld+json\">([\\s\\S]*)[\\n?]</script>`. Also triggered by a mistyped claim name that yields a non-content page.","commonSituations":"Odysee front-end markup changed after the regex was written, datacenter IP blocked and served a challenge page, or the URL points at a channel/livestream rather than a claim with a playable content URL.","solutions":["Dump the response body (err is nil, so re-fetch the URL manually with the same headers) and inspect what page Odysee actually served","Confirm the claim URL opens in a browser and shows a video with an ld+json block in view-source","If the markup changed, update regScript in extractors/odysee/odysee.go to match the current script tag layout","If a challenge page is served, retry from a residential IP or with browser-like headers"],"exampleFix":"// before\nmatchPayload := regScript.FindSubmatch(b)\nif len(matchPayload) < 2 {\n    return nil, errors.New(\"Could not read page data\")\n}\n\n// after (diagnose what was actually served before failing)\nmatchPayload := regScript.FindSubmatch(b)\nif len(matchPayload) < 2 {\n    return nil, fmt.Errorf(\"could not read page data: no ld+json block in %d bytes (served title: %q)\",\n        len(b), utils.MatchOneOf(string(b), `<title>(.*?)</title>`))\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, err := odysee.Extract(url, opts)\nif err != nil {\n    if strings.Contains(err.Error(), \"Could not read page data\") {\n        // page served without ld+json: markup change or bot wall; log and skip\n    }\n    return err\n}","preventionTips":["Monitor Odysee markup changes; this error is the first symptom of a regex drift","Fetch with browser-like headers from non-datacenter IPs to avoid challenge pages","Wrap batch runs so one changed page does not abort everything"],"tags":["odysee","html-parsing","regex","site-layout-change"],"backgroundTag":null,"analyzedSha":"dd00f6d258d80b6684a0b9402d7124e5c18ef42f","analyzedAt":"2026-08-15T16:57:31.080Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}