{"record":{"id":"0bb3477017ef8792","repo":"AlistGo/alist","slug":"r-msg-0bb347","errorCode":null,"errorMessage":"r.Msg","messagePattern":"r\\.Msg","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/cloudreve_v4/util.go","lineNumber":74,"sourceCode":"\n\tresp, err := req.Execute(method, u)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !resp.IsSuccess() {\n\t\treturn errors.New(resp.String())\n\t}\n\n\tif r.Code != 0 {\n\t\tif r.Code == 401 && d.RefreshToken != \"\" && path != \"/session/token/refresh\" {\n\t\t\t// try to refresh token\n\t\t\terr = d.refreshToken()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn d.request(method, path, callback, out)\n\t\t}\n\t\treturn errors.New(r.Msg)\n\t}\n\n\tif out != nil && r.Data != nil {\n\t\tvar marshal []byte\n\t\tmarshal, err = json.Marshal(r.Data)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\terr = json.Unmarshal(marshal, out)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (d *CloudreveV4) login() error {","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/cloudreve_v4/util.go#L56-L92","documentation":"CloudreveV4's API-envelope error: HTTP was 2xx but r.Code != 0 and the case is not the refreshable-401 path, so the server's message (r.Msg) is returned directly. Every V4 driver operation funnels through this single check.","triggerScenarios":"Any authenticated V4 call whose body code is non-zero: expired access token when no RefreshToken is set, insufficient permission, nonexistent path, or the server refusing the specific operation. The 401 branch only self-heals when d.RefreshToken is non-empty and the path is not the refresh endpoint itself.","commonSituations":"Access/refresh tokens expired and revoked (server restarted, user logged out all sessions); wrong root path; read-only account; token refresh failing because the refresh token was single-use and already consumed.","solutions":["Re-save the storage so the driver performs a fresh login and stores new tokens.","Verify the account still exists and its password unchanged on the Cloudrebve V4 server.","Check the path/root folder configuration still points to an existing directory.","Inspect the V4 server logs for the failing route to see the exact reason behind r.Msg."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := d.request(method, path, cb, out); err != nil {\n    if d.RefreshToken != \"\" && isAuthCode(err) { // r.Code==401 path already retries once\n        if rerr := d.refreshToken(); rerr == nil {\n            return d.request(method, path, cb, out)\n        }\n        return d.login() // full re-login when refresh token is exhausted\n    }\n    return err\n}","preventionTips":["Re-save the storage periodically to rotate tokens","Do not log out all sessions on the V4 user used for mounting (revokes refresh tokens)","Keep username/password configured so full re-login remains possible"],"tags":["cloudreve-v4","api-error","authentication","token-expired","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}