{"record":{"id":"ee8abea7f7cd5429","repo":"AlistGo/alist","slug":"invalid-line-s-because-file-name-can-t-be-empty-ee8abe","errorCode":null,"errorMessage":"invalid line: %s, because file name can't be empty","messagePattern":"invalid line: (.+?), because file name can't be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/url_tree/util.go","lineNumber":119,"sourceCode":"\t\treturn nil, fmt.Errorf(\"invalid line: %s, because url is required for file\", line)\n\t}\n\tindex := strings.Index(line, \"http://\")\n\tif index == -1 {\n\t\tindex = strings.Index(line, \"https://\")\n\t}\n\turl := line[index:]\n\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}","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/url_tree/util.go#L101-L137","documentation":"After stripping the trailing ':' from the metadata segment of a url_tree file line, the remaining string is empty — meaning the line looks like ':https://...' with no file name at all. A file node requires a name, so parseFileLine rejects it.","triggerScenarios":"Lines where the only pre-URL content is ':' (e.g. ':1024:https://x' is fine because name is empty but parts exist — actually the check fires when info after removing ':' is empty, i.e. exactly ':https://...' or '::https://...' trimmed cases yielding empty info string).","commonSituations":"Deleting the file name while keeping separators, or attempting to use ':' alone to denote 'use URL basename' (the driver does not support that; omit the whole prefix instead).","solutions":["Provide a real file name before the first ':' (name:URL).","If you want the URL's last path segment as the name, drop the entire metadata prefix and use the bare URL line.","Check for accidental leading ':' after copy-paste edits."],"exampleFix":"// before\n: https://x/files/a.mp4\n\n// after\nhttps://x/files/a.mp4   // name defaults to 'a.mp4'","handlingStrategy":"validation","validationCode":"func validateNonEmptyName(line string) error {\n    idx := strings.Index(line, \"http\")\n    if idx <= 0 { return nil }\n    info := strings.TrimSuffix(line[:idx], \":\")\n    if strings.TrimSpace(info) == \"\" {\n        return fmt.Errorf(\"file name missing before URL\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"file name can't be empty\") { /* add a name or drop the leading ':' */ }","preventionTips":["Never use a bare ':' prefix to imply URL-derived names — omit the prefix instead","Check for leading ':' after editing structures"],"tags":["url-tree","parsing","config","validation"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}