{"record":{"id":"8ea73d263fa248a8","repo":"glanceapp/glance","slug":"no-token-found-in-challenge-page","errorCode":null,"errorMessage":"no token found in challenge page","messagePattern":"no token found in challenge page","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/glance/widget-reddit.go","lineNumber":420,"sourceCode":"\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\n\t}\n\n\tsetBrowserUserAgentHeader(request)\n","sourceCodeStart":402,"sourceCodeEnd":438,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/widget-reddit.go#L402-L438","documentation":"Thrown by fetchRedditLoidCookie (internal/glance/widget-reddit.go:420) when the challenge page did match redditChallengePattern but the second regex, redditTokenPattern, found no token. Both the challenge string and the token must be extracted to build the solution URL (?solution=...&js_challenge=1&token=...); a page that contains the challenge markup but not the token means Reddit altered only the token part of the page (or the match in 120 is a false positive on unrelated HTML).","triggerScenarios":"The 200 response body contains something matching redditChallengePattern but nothing matching redditTokenPattern: partial Reddit page redesign where the token moved, a truncated response body (connection reset mid-read is a different error, but truncated HTML from a proxy is not), or the challenge pattern matching stale/unrelated markup.","commonSituations":"Reddit A/B-testing a new challenge page variant, old Glance version after a partial Reddit change, proxies or middleboxes stripping script blocks containing the token.","solutions":["Update Glance to the latest version (token/challenge regexes are updated together when Reddit changes)","Verify with curl -A <browser-UA> https://www.reddit.com/ that the challenge page still contains both the challenge and token fields","Try from a different IP/network to exclude block pages","If a cached loid cookie exists, wait for network conditions to change — Glance reuses the cached value"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"no token found in challenge page\") {\n    // same class as 'no JS challenge found': page-shape drift; retry later\n}","preventionTips":["Update Glance when Reddit changes its challenge page","Rely on the ~6h cached loid cookie window","Test egress path with curl using a browser User-Agent"],"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"}