{"record":{"id":"820911202ff09096","repo":"AlistGo/alist","slug":"r-msg","errorCode":null,"errorMessage":"r.Msg","messagePattern":"r\\.Msg","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/cloudreve/util.go","lineNumber":78,"sourceCode":"\t}\n\tif !resp.IsSuccess() {\n\t\treturn errors.New(resp.String())\n\t}\n\n\tif r.Code != 0 {\n\n\t\t// 刷新 cookie\n\t\tif r.Code == http.StatusUnauthorized && path != loginPath {\n\t\t\tif d.Username != \"\" && d.Password != \"\" {\n\t\t\t\terr = d.login()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\treturn d.request(method, path, callback, out)\n\t\t\t}\n\t\t}\n\n\t\treturn errors.New(r.Msg)\n\t}\n\tsess := cookie.GetCookie(resp.Cookies(), \"cloudreve-session\")\n\tif sess != nil {\n\t\td.Cookie = sess.Value\n\t}\n\tif out != nil && r.Data != nil {\n\t\tvar marshal []byte\n\t\tmarshal, err = jsoniter.Marshal(r.Data)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\terr = jsoniter.Unmarshal(marshal, out)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/cloudreve/util.go#L60-L96","documentation":"Returned by Cloudreve driver's request helper when the HTTP call succeeded but the Cloudreve response envelope carries a non-zero business code (r.Code != 0). The server's own message field (r.Msg) is wrapped verbatim, so the text is whatever the Cloudreve instance replied (e.g. 'object not found', 'unauthorized'). It is the catch-all API-level error for every authenticated Cloudreve call that is not a 401-relogin case.","triggerScenarios":"Any driver operation (List/MakeDir/Move/Rename/Copy/Delete/upload callback) where POST/GET to the Cloudreve API answers 200 HTTP but JSON body code != 0, and either the code is not 401 or Username/Password are empty so re-login cannot be attempted. Typical when the session cookie expired and no credentials were configured, the path no longer exists, or the server rejects the operation.","commonSituations":"Expired cloudreve-session cookie with no username/password filled in the driver addition; wrong root folder ID/path after it was moved or deleted on the server; Cloudrebve upgraded and changed API semantics; read-only or permission-restricted sub-account used for mounting.","solutions":["Fill in Username and Password in the driver config so an expired session triggers automatic re-login (the code retries once after d.login()).","Re-save the driver storage to force a fresh login and cookie, then retry the failed operation.","Verify the target path/ID still exists and the account has permission for the failing operation on the Cloudreve side.","Check Cloudreve server logs at the same timestamp to see the real reason behind r.Msg."],"exampleFix":"// before: driver addition left Username/Password empty -> expired cookie surfaces raw r.Msg\n// after: configure credentials so request() can self-heal\n// (in storage addition)\n//   username: your-user\n//   password: your-pass\n// util.go keeps: if r.Code == 401 && d.Username != \"\" { d.login(); return d.request(...) }","handlingStrategy":"retry","validationCode":"// before mounting, verify the session works and credentials allow re-login\nif _, err := d.List(ctx, model.Obj(&model.Object{Path: \"/\"})); err != nil {\n    if d.Addition.Username == \"\" || d.Addition.Password == \"\" {\n        return fmt.Errorf(\"api error %q and no credentials configured for re-login\", err)\n    }\n}","typeGuard":"func isCloudreveApiMsg(err error) bool {\n    // envelope errors surface verbatim; distinguish from transport errors\n    var ue *url.Error\n    return err != nil && errors.As(err, &ue) == false && err.Error() != \"\"\n}","tryCatchPattern":"if err := d.request(method, path, cb, out); err != nil {\n    if strings.Contains(err.Error(), \"unauthorized\") { // session expired\n        if lerr := d.login(); lerr == nil {\n            err = d.request(method, path, cb, out) // one retry after re-login\n        }\n    }\n    return err\n}","preventionTips":["Always configure Username/Password in the driver addition so expired sessions self-heal","Monitor r.Msg values in logs to catch permission/path drift early","Keep driver and Cloudreve server versions aligned"],"tags":["cloudreve","go","api-error","authentication","session-expired"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}