{"record":{"id":"785a0c7e0d398fae","repo":"AlistGo/alist","slug":"missing-owner-qid-for-cookie-mode","errorCode":null,"errorMessage":"missing owner_qid for cookie mode","messagePattern":"missing owner_qid for cookie mode","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/yunpan360/util.go","lineNumber":502,"sourceCode":"\t\tif ownerQID != \"\" {\n\t\t\treturn ownerQID, nil\n\t\t}\n\t}\n\n\tresp, err := d.listCookiePage(ctx, d.RootFolderPath, 0, 1)\n\tif err == nil && resp != nil {\n\t\townerQID = firstNonEmpty(ownerQID, resp.GetOwnerQID())\n\t}\n\tif ownerQID != \"\" {\n\t\treturn ownerQID, nil\n\t}\n\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 {","sourceCodeStart":484,"sourceCodeEnd":520,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/yunpan360/util.go#L484-L520","documentation":"resolveCookieOwnerQID exhausted every source of the owner_qid form field — driver config, the YunpanObject's embedded OwnerQID, the listing response, and the scraped index page — and still found nothing (drivers/yunpan360/util.go:502). Cookie-mode operations like rename/move/recycle that need owner_qid will fail with this error.","triggerScenarios":"Any cookie-mode mutation (rename, move, recycle) or download param resolution when OwnerQID is absent from storage config, absent from listed objects, and page scraping returns nothing. The listing API (resp.GetOwnerQID()) also returned empty.","commonSituations":"Fresh storage setup where OwnerQID was never configured; 360 changed the index page HTML so parseCookieDownloadSessionFromText finds no owner QID; shared-file scenarios where the listing response omits owner info.","solutions":["Set OwnerQID explicitly in the storage configuration","Refresh the cookie from a current browser session (full cookie string, all key values)","Re-list the directory: objects freshly listed carry OwnerQID which is picked up per-object","If the error appears after a 360 web update, the page parser in the driver needs updating"],"exampleFix":"// before\nstorage.Setting(\"owner_qid\", \"\")\n\n// after\nstorage.Setting(\"owner_qid\", \"360100000012345678\")","handlingStrategy":"validation","validationCode":"if sanitizeOwnerQID(d.OwnerQID) == \"\" { return errors.New(\"configure owner_qid before cookie operations\") }","typeGuard":"func hasOwnerQID(q string) bool { return sanitizeOwnerQID(q) != \"\" }","tryCatchPattern":"q, err := d.resolveCookieOwnerQID(ctx, obj, false)\nif err != nil {\n    if strings.Contains(err.Error(), \"owner_qid\") {\n        q, err = d.resolveCookieOwnerQID(ctx, obj, true) // force refresh pass\n    }\n    if err != nil { return err }\n}","preventionTips":["Keep OwnerQID in config as the baseline; per-object values are a bonus","Refresh cookie when scraping starts failing — layout changes hit the parser first","Re-list directories after cookie changes so objects pick up fresh owner data"],"tags":["yunpan360","cookie","config","scraping"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}