{"record":{"id":"db72db472c61af67","repo":"AlistGo/alist","slug":"failed-to-parse-cookie-download-session-from-page","errorCode":null,"errorMessage":"failed to parse cookie download session from page","messagePattern":"failed to parse cookie download session from page","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/yunpan360/util.go","lineNumber":514,"sourceCode":"\n\tpageSession, err := d.getCookieDownloadSessionFromPage(ctx)\n\tif err == nil && pageSession != nil {\n\t\townerQID = firstNonEmpty(ownerQID, pageSession.OwnerQID)\n\t}\n\tif ownerQID == \"\" {\n\t\treturn \"\", errors.New(\"missing owner_qid for cookie mode\")\n\t}\n\treturn ownerQID, nil\n}\n\nfunc (d *Yunpan360) getCookieDownloadSessionFromPage(ctx context.Context) (*CookieDownloadSession, error) {\n\tbody, err := d.cookiePage(ctx, indexPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tsession := parseCookieDownloadSessionFromText(string(body))\n\tif session == nil {\n\t\treturn nil, errors.New(\"failed to parse cookie download session from page\")\n\t}\n\td.cacheCookieSession(session)\n\treturn session, nil\n}\n\nfunc (d *Yunpan360) getCachedCookieDownloadSession() *CookieDownloadSession {\n\td.authMu.Lock()\n\tdefer d.authMu.Unlock()\n\n\tif d.cachedCookieSession == nil || time.Now().After(d.cookieSessionExpire) {\n\t\treturn nil\n\t}\n\tsession := *d.cachedCookieSession\n\treturn &session\n}\n\nfunc (d *Yunpan360) cacheCookieDownloadSession(ownerQID, token string) {\n\td.cacheCookieSession(&CookieDownloadSession{","sourceCodeStart":496,"sourceCodeEnd":532,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/yunpan360/util.go#L496-L532","documentation":"getCookieDownloadSessionFromPage fetched the yunpan360 index HTML page successfully, but parseCookieDownloadSessionFromText could not extract the (owner_qid, download_token) session data embedded in it (drivers/yunpan360/util.go:514). This is a scraping failure, not an HTTP failure.","triggerScenarios":"The driver requests indexPath and the returned HTML no longer matches the patterns the parser expects — e.g. 360 redesigned the page, the page returned a login/redirect page because the cookie is invalid, or the page is region-gated/anti-bot content.","commonSituations":"Expired cookie making the index page redirect to a login page; 360 frontend deploy changes variable names in the inline JS that holds the session; accessing from an IP/region where a captcha page is served instead.","solutions":["Refresh the cookie in storage config with a fresh browser session and retry","Open yunpan360.com in the browser with the same cookie and confirm the download page renders normally (no captcha/login)","Check for driver updates — page-format changes require a parser fix in the driver","Capture the page (d.cookiePage output) and compare its structure with what parseCookieDownloadSessionFromText expects"],"exampleFix":"// before: stale cookie yields login page, parser returns nil\nsession, err := d.getCookieDownloadSessionFromPage(ctx)\n\n// after: refresh cookie first, then scrape\n// storage.Setting(\"cookie\", freshCookie)\nsession, err := d.getCookieDownloadSessionFromPage(ctx)","handlingStrategy":"fallback","validationCode":null,"typeGuard":"func isScrapeFailure(err error) bool { return err != nil && strings.Contains(err.Error(), \"parse cookie download session\") }","tryCatchPattern":"session, err := d.getCookieDownloadSessionFromPage(ctx)\nif err != nil {\n    // fall back to cached/config values if available\n    if s := d.getCachedCookieSession(); s != nil { session = s } else { return nil, err }\n}","preventionTips":["Treat page-scrape code as fragile: pin driver versions and update together with 360 web changes","Validate cookies by fetching a known page in a smoke test before heavy use","Cache sessions (the driver does) so transient page changes don't break every call"],"tags":["yunpan360","scraping","cookie","html","fragile"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}