{"record":{"id":"6dd9cbe3a1bfe686","repo":"AlistGo/alist","slug":"invalid-file-size-6dd9cb","errorCode":null,"errorMessage":"invalid file size","messagePattern":"invalid file size","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/guangyapan/driver.go","lineNumber":385,"sourceCode":"\tif !strings.EqualFold(strings.TrimSpace(out.Msg), \"success\") {\n\t\treturn fmt.Errorf(\"copy failed: %s\", strings.TrimSpace(out.Msg))\n\t}\n\ttaskID := strings.TrimSpace(out.Data.TaskID)\n\tif taskID == \"\" {\n\t\treturn nil\n\t}\n\treturn d.waitTaskDone(ctx, taskID)\n}\n\nfunc (d *GuangYaPan) Put(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up driver.UpdateProgress) error {\n\tif err := d.ensureAccessToken(ctx); err != nil {\n\t\treturn err\n\t}\n\tif file == nil {\n\t\treturn errors.New(\"file is nil\")\n\t}\n\tif file.GetSize() < 0 {\n\t\treturn errors.New(\"invalid file size\")\n\t}\n\tname := strings.TrimSpace(file.GetName())\n\tif name == \"\" {\n\t\treturn errors.New(\"file name is empty\")\n\t}\n\n\tparentID := dstDir.GetID()\n\n\ttoken, code, err := d.getUploadToken(ctx, parentID, name, file.GetSize())\n\tif err != nil {\n\t\treturn err\n\t}\n\ttaskID := strings.TrimSpace(token.TaskID)\n\tif code == 156 {\n\t\tif taskID == \"\" {\n\t\t\treturn errors.New(\"instant upload returns empty task id\")\n\t\t}\n\t\treturn d.waitUploadTaskInfo(ctx, taskID)","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/guangyapan/driver.go#L367-L403","documentation":"GuangYaPan Put rejects files with GetSize() < 0. The provider's upload-token API requires an exact content length (it is used for instant-upload matching and OSS multipart planning), so a stream of unknown size cannot be uploaded through this driver.","triggerScenarios":"Uploading a streamer that reports a negative size — typically model.UNKNOWN_SIZE (-1) used for chunked/streaming bodies where the length is not known in advance.","commonSituations":"WebDAV/FTP edge clients sending chunked transfer-encoding without Content-Length; piping stdin or a pipe reader into the upload; proxies stripping content length.","solutions":["Buffer the stream first so its size is known, then upload (e.g. spool to a temp file)","Send a correct Content-Length header from the client (avoid chunked encoding)","If using the SDK, wrap the reader in a streamer constructed with the actual length"],"exampleFix":"// before: unknown-length stream -> Put fails\n// after: spool to temp file to fix the size\nf, _ := os.CreateTemp(\"\", \"upload-*\")\nio.Copy(f, src)\nf.Seek(0, io.SeekStart)\nstream := model.NewFileStream(&model.Obj{Name: name, Size: fi.Size()}, f)","handlingStrategy":"validation","validationCode":"if file.GetSize() < 0 {\n\treturn errors.New(\"file size unknown; provide Content-Length or spool to disk\")\n}\nreturn d.Put(ctx, dstDir, file, up)","typeGuard":"func hasKnownSize(f model.FileStreamer) bool { return f != nil && f.GetSize() >= 0 }","tryCatchPattern":"if err := d.Put(ctx, dir, file, up); err != nil {\n\tif strings.Contains(err.Error(), \"invalid file size\") {\n\t\tspooled := spoolToTemp(file) // buffer to fix the length\n\t\treturn d.Put(ctx, dir, spooled, up)\n\t}\n\treturn err\n}","preventionTips":["Send explicit Content-Length from clients; avoid chunked transfer-encoding for uploads","Spool unknown-length streams to a temp file before uploading","Log stream sizes at the edge to catch -1 (UNKNOWN_SIZE) early"],"tags":["guangyapan","upload","content-length","validation"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}