{"record":{"id":"ed0fb4363789cd3d","repo":"AlistGo/alist","slug":"invalid-line-s-because-file-size-must-be-an-int-ed0fb4","errorCode":null,"errorMessage":"invalid line: %s, because file size must be an integer","messagePattern":"invalid line: (.+?), because file size must be an integer","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/url_tree/util.go","lineNumber":126,"sourceCode":"\tinfo := line[:index]\n\tnode := &Node{\n\t\tUrl: url,\n\t}\n\thaveSize := false\n\tif index > 0 {\n\t\tif !strings.HasSuffix(info, \":\") {\n\t\t\treturn nil, fmt.Errorf(\"invalid line: %s, because file info must end with ':'\", line)\n\t\t}\n\t\tinfo = info[:len(info)-1]\n\t\tif info == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"invalid line: %s, because file name can't be empty\", line)\n\t\t}\n\t\tinfoParts := strings.Split(info, \":\")\n\t\tnode.Name = infoParts[0]\n\t\tif len(infoParts) > 1 {\n\t\t\tsize, err := strconv.ParseInt(infoParts[1], 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid line: %s, because file size must be an integer\", line)\n\t\t\t}\n\t\t\tnode.Size = size\n\t\t\thaveSize = true\n\t\t\tif len(infoParts) > 2 {\n\t\t\t\tmodified, err := strconv.ParseInt(infoParts[2], 10, 64)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"invalid line: %s, because file modified must be an unix timestamp\", line)\n\t\t\t\t}\n\t\t\t\tnode.Modified = modified\n\t\t\t}\n\t\t}\n\t} else {\n\t\tnode.Name = stdpath.Base(url)\n\t}\n\tif !haveSize && headSize {\n\t\tsize, err := getSizeFromUrl(url)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"get size from url error: %s\", err)","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/url_tree/util.go#L108-L144","documentation":"In a url_tree line 'Name:Size:...', the second colon-separated field must parse as a base-10 64-bit integer via strconv.ParseInt. Any non-numeric size (or overflow) fails and aborts tree parsing with the offending line included.","triggerScenarios":"Sizes like '1.5GB', '10K', negative values encoded oddly, empty size field ('name::https://...' yields '' -> ParseInt error), or numbers exceeding int64.","commonSituations":"Human-readable sizes pasted from a file listing, localized number formats (commas), or forgetting the size must be in bytes. Error surfaces at Init.","solutions":["Write sizes as plain byte counts, e.g. movie.mp4:1073741824: https://x/m.mp4.","Omit size entirely (name:URL) if unknown — with head_size enabled the driver can HEAD the URL to fill it in.","Remove thousands separators and units from size fields."],"exampleFix":"// before\nmovie.mp4:1.5GB: https://x/m.mp4\n\n// after\nmovie.mp4:1610612736: https://x/m.mp4","handlingStrategy":"validation","validationCode":"func validateSizeField(line string) error {\n    idx := strings.Index(line, \"http\")\n    if idx <= 0 { return nil }\n    info := strings.TrimSuffix(line[:idx], \":\")\n    parts := strings.Split(info, \":\")\n    if len(parts) > 1 && parts[1] != \"\" {\n        if _, err := strconv.ParseInt(parts[1], 10, 64); err != nil {\n            return fmt.Errorf(\"size %q must be integer bytes\", parts[1])\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"file size must be an integer\") { /* convert human sizes to bytes or omit the field */ }","preventionTips":["Sizes are raw byte integers only","Omit size and enable head_size when sizes are unknown","Strip units/commas when converting listings"],"tags":["url-tree","parsing","config","validation"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}