{"record":{"id":"69e5e20e9977b6d9","repo":"AlistGo/alist","slug":"invalid-line-s-because-file-modified-must-be-an-69e5e2","errorCode":null,"errorMessage":"invalid line: %s, because file modified must be an unix timestamp","messagePattern":"invalid line: (.+?), because file modified must be an unix timestamp","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/url_tree/util.go","lineNumber":133,"sourceCode":"\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)\n\t\t} else {\n\t\t\tnode.Size = size\n\t\t}\n\t}\n\treturn node, nil\n}\n","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/url_tree/util.go#L115-L151","documentation":"The optional third metadata field of a url_tree line is a Unix timestamp (seconds). strconv.ParseInt over it failing — non-numeric, fractional like '2024-01-01', or float epoch — produces this error with the whole line echoed.","triggerScenarios":"Lines 'Name:Size:Modified:URL' where Modified is a date string ('2024-01-01'), an ISO timestamp, a float, or accidentally a URL fragment due to miscounted colons.","commonSituations":"Converting from human-readable listings, or misaligned colon fields where a name containing ':' shifts positions (e.g. 'a:b:1024:1700000000:URL' makes Modified parse '1700000000' but extra fields confuse earlier ones).","solutions":["Use integer Unix seconds: movie.mp4:1024:1700000000: https://x/m.mp4.","Omit modified (Name:Size:URL) if not needed.","Avoid ':' inside file names — it is the field separator."],"exampleFix":"// before\nmovie.mp4:1024:2024-01-01: https://x/m.mp4\n\n// after\nmovie.mp4:1024:1704153600: https://x/m.mp4","handlingStrategy":"validation","validationCode":"func validateModifiedField(line string) error {\n    idx := strings.Index(line, \"http\")\n    if idx <= 0 { return nil }\n    parts := strings.Split(strings.TrimSuffix(line[:idx], \":\"), \":\")\n    if len(parts) > 2 && parts[2] != \"\" {\n        if _, err := strconv.ParseInt(parts[2], 10, 64); err != nil {\n            return fmt.Errorf(\"modified %q must be unix seconds\", parts[2])\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"must be an unix timestamp\") { /* replace dates with epoch seconds */ }","preventionTips":["Use Unix epoch seconds, never ISO dates","Keep field order Name:Size:Modified","Avoid ':' in file names"],"tags":["url-tree","parsing","timestamp","config"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}