{"record":{"id":"3b24a25e99163ef5","repo":"AlistGo/alist","slug":"baidu-youth-sk-is-empty","errorCode":null,"errorMessage":"baidu youth sk is empty","messagePattern":"baidu youth sk is empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/baidu_youth/util.go","lineNumber":326,"sourceCode":"\t}\n}\n\nfunc nextDPLogID() string {\n\treturn strconv.FormatInt(time.Now().UnixNano(), 10)\n}\n\nfunc (d *BaiduYouth) getCurrentUserSK(ctx context.Context) (string, error) {\n\tsk, err := d.getUserSK(ctx)\n\tif err == nil && sk != \"\" {\n\t\treturn sk, nil\n\t}\n\tif d.sk != \"\" {\n\t\treturn d.sk, nil\n\t}\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn \"\", fmt.Errorf(\"baidu youth sk is empty\")\n}\n\nfunc (d *BaiduYouth) locatedownloadRand(sk string, nowMilli int64) string {\n\tsum := sha1.Sum([]byte(strconv.FormatInt(d.uk, 10) + sk + strconv.FormatInt(nowMilli, 10) + \"0\"))\n\treturn hex.EncodeToString(sum[:])\n}\n\nfunc (d *BaiduYouth) locatedownloadSign(fileMD5 string, fileID string, nowMilli int64) string {\n\tsum := md5.Sum([]byte(fileMD5 + \"_\" + strconv.FormatInt(d.uk, 10) + \"_\" + fileID + \"_\" + strconv.FormatInt(nowMilli, 10)))\n\treturn hex.EncodeToString(sum[:])\n}\n\nfunc (d *BaiduYouth) resolveDownloadMeta(ctx context.Context, file model.Obj) (string, string, string, error) {\n\tparentDir := stdpath.Dir(file.GetPath())\n\tif parentDir == \".\" {\n\t\tparentDir = \"/\"\n\t}\n","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/baidu_youth/util.go#L308-L344","documentation":"Returned by BaiduYouth.getCurrentUserSK (drivers/baidu_youth/util.go:326): both the live getUserSK call and the cached d.sk came back empty (and getUserSK itself reported no error). The sk is the secret key used to compute the rand signature for locatedownload; an empty sk means downloads cannot be signed.","triggerScenarios":"getLocateDownloadURL -> getCurrentUserSK when the sk API returns an empty-but-successful response and the driver was never initialized with an sk: fresh/expired cookies or a changed API shape.","commonSituations":"Cookie set valid enough for listing but missing the session state that yields sk; Baidu changed the sk endpoint response; long-lived process whose sk cache never got populated.","solutions":["Re-init the storage with fresh cookies so the sk fetch runs again during bootstrap","Verify the sk endpoint (getUserSK) actually returns content with current cookies","Persist/cache the sk at init time so per-download calls have a fallback"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"url, err := d.getLocateDownloadURL(ctx, file)\nif err != nil && strings.Contains(err.Error(), \"sk is empty\") {\n    if ierr := d.Init(ctx); ierr == nil { // re-bootstrap caches sk\n        url, err = d.getLocateDownloadURL(ctx, file)\n    }\n}","preventionTips":["Populate sk during Init so per-download calls have a warm cache","Refresh cookies at the first sign of auth weirdness — sk, uk and bdstoken expire together","Do not sign requests with an sk you never verified non-empty"],"tags":["baidu-youth","auth","signing","config"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}