{"record":{"id":"42a6afa2544f851c","repo":"AlistGo/alist","slug":"mediafire-token-renewal-failed-s","errorCode":null,"errorMessage":"MediaFire token renewal failed: %s","messagePattern":"MediaFire token renewal failed: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/mediafire/util.go","lineNumber":133,"sourceCode":"}\n\nfunc (d *Mediafire) renewToken(_ context.Context) error {\n\tquery := map[string]string{\n\t\t\"session_token\":   d.SessionToken,\n\t\t\"response_format\": \"json\",\n\t}\n\n\tvar resp MediafireRenewTokenResponse\n\t_, err := d.postForm(\"/user/renew_session_token.php\", query, &resp)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to renew token: %w\", err)\n\t}\n\n\t//fmt.Printf(\"getInfo :: Raw response: %s\\n\", string(body))\n\t//fmt.Printf(\"getInfo :: Parsed response: %+v\\n\", resp)\n\n\tif resp.Response.Result != \"Success\" {\n\t\treturn fmt.Errorf(\"MediaFire token renewal failed: %s\", resp.Response.Result)\n\t}\n\n\td.SessionToken = resp.Response.SessionToken\n\n\t//fmt.Printf(\"Init :: Renew Session Token: %s\", resp.Response.Result)\n\n\top.MustSaveDriverStorage(d)\n\n\treturn nil\n}\n\nfunc (d *Mediafire) getFiles(ctx context.Context, folderKey string) ([]File, error) {\n\tfiles := make([]File, 0)\n\thasMore := true\n\tchunkNumber := 1\n\n\tfor hasMore {\n\t\tresp, err := d.getFolderContent(ctx, folderKey, chunkNumber)","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/mediafire/util.go#L115-L151","documentation":"renewToken reached MediaFire, got a parseable response, but response.result != 'Success' — the API refused to renew the session token. MediaFire rejects renewal when the current session_token is already expired/revoked, when the cookie/account context no longer matches, or when the endpoint is called too frequently. The new token in response.session_token is intentionally not saved on this path.","triggerScenarios":"The 6-9 minute renewal cron racing after the token already expired; account logged out in the browser invalidating the session; renewing with a token obtained under a different cookie.","commonSituations":"Instance suspended/resumed so the cron gap exceeded the token lifetime; multiple instances sharing one account and interfering with each other's sessions.","solutions":["On this error, immediately fall back to getSessionToken with a freshly extracted browser cookie — renewal of a dead token cannot succeed","Ensure only one instance renews a given account's token","If it recurs, re-extract both cookie and session token together so they belong to the same browser session"],"exampleFix":"// before: renew failure returned as-is\nif resp.Response.Result != \"Success\" {\n    return fmt.Errorf(\"MediaFire token renewal failed: %s\", resp.Response.Result)\n}\n\n// after: escalate dead-token renewals to full re-auth\nif resp.Response.Result != \"Success\" {\n    if newTok, err2 := d.getSessionToken(context.Background()); err2 == nil {\n        d.SessionToken = newTok\n        return nil\n    }\n    return fmt.Errorf(\"MediaFire token renewal failed: %s\", resp.Response.Result)\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"On renewal refusal, fall back immediately: if newTok, err := d.getSessionToken(ctx); err == nil { use newTok } else { mark storage as needing new credentials }. Retrying renew against a dead token is pointless.","preventionTips":["Detect token-expiry result strings and switch to full re-auth instead of retrying renew","Ensure renewal cadence (6-9 min cron) is shorter than MediaFire's session lifetime","Run only one instance per MediaFire account to avoid mutual session invalidation"],"tags":["mediafire","token-renewal","session-expiry","authentication"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}