{"record":{"id":"ac3be61436f06524","repo":"AlistGo/alist","slug":"yunpan-upload-request-failed-errno-d","errorCode":null,"errorMessage":"yunpan upload request failed: errno=%d","messagePattern":"yunpan upload request failed: errno=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/yunpan360/upload.go","lineNumber":637,"sourceCode":"\n\trespBody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif resp.StatusCode >= http.StatusBadRequest {\n\t\treturn fmt.Errorf(\"yunpan upload request failed: status=%d body=%s\", resp.StatusCode, strings.TrimSpace(string(respBody)))\n\t}\n\treturn decodeUploadResp(respBody, out)\n}\n\nfunc decodeUploadResp(body []byte, out interface{}) error {\n\tvar env uploadEnvelope\n\tif err := utils.Json.Unmarshal(body, &env); err != nil {\n\t\treturn err\n\t}\n\tif env.Errno != nil && *env.Errno != 0 {\n\t\tif env.Errmsg == \"\" {\n\t\t\treturn fmt.Errorf(\"yunpan upload request failed: errno=%d\", *env.Errno)\n\t\t}\n\t\treturn errors.New(env.Errmsg)\n\t}\n\tif env.Errno == nil && strings.TrimSpace(env.Errmsg) != \"\" && len(env.Data) > 0 && string(env.Data) == \"[]\" {\n\t\treturn errors.New(env.Errmsg)\n\t}\n\tif out == nil {\n\t\treturn nil\n\t}\n\tif err := utils.Json.Unmarshal(body, out); err != nil {\n\t\tif strings.TrimSpace(env.Errmsg) != \"\" {\n\t\t\treturn errors.New(env.Errmsg)\n\t\t}\n\t\treturn err\n\t}\n\treturn nil\n}\n","sourceCodeStart":619,"sourceCodeEnd":655,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/yunpan360/upload.go#L619-L655","documentation":"Thrown in decodeUploadResp when the JSON envelope parsed fine but env.Errno is a non-nil pointer to a non-zero value AND env.Errmsg is empty — i.e. the 360 yunpan upload API reported a business failure code without a human-readable message. The driver falls back to printing the bare errno.","triggerScenarios":"Upload API returning errno like session-expired, quota-exceeded, or file-rejected with Errmsg stripped; cookie auth invalid; file type blocked; anti-abuse throttle codes that omit messages.","commonSituations":"Expired cookie session where the upload endpoint signals only by errno; hitting upload frequency limits; uploading files the pan classifies as unsafe; API version changes introducing new unmapped errno values.","solutions":["Refresh the Cookie credential and retry — session errno is the most common silent code","Look up the numeric errno against 360 yunpan error tables (or capture a web-UI upload via devtools to see its meaning)","Verify account quota and file type restrictions in the web UI","Retry after a delay if the errno corresponds to throttling"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if strings.TrimSpace(d.Cookie) == \"\" {\n    return errors.New(\"yunpan360: cookie missing; upload will fail with bare errno\")\n}","typeGuard":null,"tryCatchPattern":"if err := decodeUploadResp(respBody, out); err != nil {\n    if strings.Contains(err.Error(), \"errno=\") {\n        code := parseErrno(err) // map known codes: session, quota, throttle\n        switch {\n        case code == errnoSessionExpired:\n            return fmt.Errorf(\"yunpan360 cookie expired, update credential: %w\", err)\n        case isThrottle(code):\n            time.Sleep(10 * time.Second)\n            return retryUpload()\n        }\n    }\n    return err\n}","preventionTips":["Maintain a mapped table of known yunpan360 errno values for actionable messages","Probe session validity with a list call before starting uploads","Log the raw response body when Errmsg is empty to discover new codes"],"tags":["yunpan360","upload","errno","api-error","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}