{"record":{"id":"fedbbc6bde4f138b","repo":"glanceapp/glance","slug":"no-js-challenge-found","errorCode":null,"errorMessage":"no JS challenge found","messagePattern":"no JS challenge found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/glance/widget-reddit.go","lineNumber":416,"sourceCode":"\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer response.Body.Close()\n\n\tif response.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"unexpected status code %d when requesting challenge page\", response.StatusCode)\n\t}\n\n\tchallengeBody, err := io.ReadAll(response.Body)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tchallengeMatches := redditChallengePattern.FindSubmatch(challengeBody)\n\ttokenMatches := redditTokenPattern.FindSubmatch(challengeBody)\n\n\tif challengeMatches == nil {\n\t\treturn \"\", fmt.Errorf(\"no JS challenge found\")\n\t}\n\n\tif tokenMatches == nil {\n\t\treturn \"\", fmt.Errorf(\"no token found in challenge page\")\n\t}\n\n\tchallengeStr := string(challengeMatches[1])\n\ttoken := string(tokenMatches[1])\n\tsolution := challengeStr + challengeStr // the JS does: e + e\n\n\tparams := url.Values{\n\t\t\"solution\":     {solution},\n\t\t\"js_challenge\": {\"1\"},\n\t\t\"token\":        {token},\n\t}\n\trequest, err = http.NewRequest(\"GET\", \"https://www.reddit.com/?\"+params.Encode(), nil)\n\tif err != nil {\n\t\treturn \"\", err","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/widget-reddit.go#L398-L434","documentation":"Thrown by fetchRedditLoidCookie (internal/glance/widget-reddit.go:416) when the page returned by https://www.reddit.com/ with status 200 does not contain the markup matched by redditChallengePattern. Glance solves Reddit's anti-bot JS challenge by regex-extracting the challenge string from the HTML; if Reddit changes the challenge page structure, stops issuing challenges, or serves a different page (block page, redirect target, localized variant), the pattern finds nothing and this error fires.","triggerScenarios":"GET https://www.reddit.com/ returns 200 but the body lacks the expected JS-challenge markup: Reddit updated/removed the challenge format, Reddit served a block/captcha page to your IP instead of a challenge, a proxy or CDN rewrote the response body, or reddit already set cookies so no challenge was needed but the body also lacks the token pattern.","commonSituations":"Running Glance from a datacenter/VPS IP that Reddit flags, running an older Glance version after Reddit changed its anti-bot page, egress through a corporate proxy that alters responses, or Reddit regional variants serving different HTML.","solutions":["Update Glance to the latest release — challenge regex fixes land frequently whenever Reddit changes the page","Run from a residential IP or different network to rule out Reddit serving a block page instead of the challenge","Check if a cached loid cookie still exists (Glance falls back to it for up to 6 hours); the widget only fully fails when there is no cache","Report the issue upstream with your Glance version so redditChallengePattern can be updated"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Go: treat as transient; Glance already falls back to a cached loid cookie.\nloid, err := getRedditLoid()\nif err != nil {\n    if strings.Contains(err.Error(), \"no JS challenge found\") {\n        // Reddit page variant or block page; retry later, use cache\n    }\n}","preventionTips":["Keep Glance updated since Reddit challenge changes require regex fixes","Avoid datacenter IPs that Reddit serves block pages to","Cache the loid cookie so brief challenge changes degrade gracefully"],"tags":["reddit","anti-bot","regex","network"],"backgroundTag":null,"analyzedSha":"91324e8de762702e97b0ac5c8e36271d644d8642","analyzedAt":"2026-08-15T14:12:54.279Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}