{"record":{"id":"be33db524da99185","repo":"AlistGo/alist","slug":"too-many-parts-please-increase-part-size","errorCode":null,"errorMessage":"Too many parts, please increase part size","messagePattern":"Too many parts, please increase part size","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/115/util.go","lineNumber":558,"sourceCode":"\t\t} else {\n\t\t\tchunk.Size = fileSize / chunkN\n\t\t}\n\t\tchunks = append(chunks, chunk)\n\t}\n\n\treturn chunks, nil\n}\n\n// SplitFileByPartSize splits big file into parts by the size of parts.\n// Splits the file by the part size. Returns the FileChunk when error is nil.\nfunc SplitFileByPartSize(fileSize int64, chunkSize int64) ([]oss.FileChunk, error) {\n\tif chunkSize <= 0 {\n\t\treturn nil, errors.New(\"chunkSize invalid\")\n\t}\n\n\tchunkN := fileSize / chunkSize\n\tif chunkN >= 10000 {\n\t\treturn nil, errors.New(\"Too many parts, please increase part size\")\n\t}\n\n\tvar chunks []oss.FileChunk\n\tchunk := oss.FileChunk{}\n\tfor i := int64(0); i < chunkN; i++ {\n\t\tchunk.Number = int(i + 1)\n\t\tchunk.Offset = i * chunkSize\n\t\tchunk.Size = chunkSize\n\t\tchunks = append(chunks, chunk)\n\t}\n\n\tif fileSize%chunkSize > 0 {\n\t\tchunk.Number = len(chunks) + 1\n\t\tchunk.Offset = int64(len(chunks)) * chunkSize\n\t\tchunk.Size = fileSize % chunkSize\n\t\tchunks = append(chunks, chunk)\n\t}\n","sourceCodeStart":540,"sourceCodeEnd":576,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/115/util.go#L540-L576","documentation":"Returned by Streamtape.callAPI when json.Unmarshal of resp.Result into the caller's typed out parameter fails. The HTTP call and envelope were fine, but the JSON inside \"result\" does not match the Go struct the driver expects (wrong field names/types) or is truncated/corrupted.","triggerScenarios":"Streamtape changes the shape of a result payload (renames fields, changes a string to a number or an object to an array) so the static struct (e.g. fileInfoResult, remoteDlStatusResult) no longer matches; a proxy truncates the body; numeric precision (e.g. large file sizes as float64) overflows the declared type.","commonSituations":"After an upstream Streamtape API revision with no driver update; mixing driver versions against a newer API; HTML error page inside a 200 envelope after CDN interception.","solutions":["Log resp.Result (raw JSON) alongside the unmarshal error to see which field mismatches, then update the corresponding struct tags/types in the driver.","Retry once — truncated responses from CDN hiccups can be transient.","Update to the latest driver version if Streamtape changed its schema; the fix is usually corrected struct definitions.","If the mismatch is numeric, switch affected fields to json.Number or float64 and convert explicitly."],"exampleFix":"// before\ntype fileInfoResult struct {\n\tSize int64 `json:\"size\"` // API now also returns \"sizestr\": \"1.5GB\"\n}\n\n// after\ntype fileInfoResult struct {\n\tSize    int64  `json:\"size\"`\n\tSizeStr string `json:\"sizestr\"`\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":"func isStreamtapeDecodeErr(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"decode streamtape result failed\")\n}","tryCatchPattern":"err := d.callAPI(ctx, endpoint, query, &out)\nif isStreamtapeDecodeErr(err) {\n\t// fall back to raw JSON handling; log raw resp.Result for schema triage\n\tvar raw json.RawMessage\n\t_ = d.callAPI(ctx, endpoint, query, &raw)\n}","preventionTips":["Update the driver whenever Streamtape revises its API.","Use json.Number or float64 for numeric fields of uncertain precision.","Capture resp.Result in logs when decode fails to speed up schema fixes."],"tags":["streamtape","json","schema-drift","upstream"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}