AlistGo/alist · error

invalid line: %s, because file info must end with ':'

Error message

invalid line: %s, because file info must end with ':'

What it means

When a url_tree file line has metadata before the URL (index of the URL > 0), that metadata section must terminate with ':' as the separator convention (FileName:FileSize:Modified:Url). If the segment immediately before the URL does not end with ':', the line grammar is violated and parsing stops.

Source

Thrown at drivers/url_tree/util.go:115

// [FileName:][FileSize:][Modified:]Url
func parseFileLine(line string, headSize bool) (*Node, error) {
	// if there is no url, it is an error
	if !strings.Contains(line, "http://") && !strings.Contains(line, "https://") {
		return nil, fmt.Errorf("invalid line: %s, because url is required for file", line)
	}
	index := strings.Index(line, "http://")
	if index == -1 {
		index = strings.Index(line, "https://")
	}
	url := line[index:]
	info := line[:index]
	node := &Node{
		Url: url,
	}
	haveSize := false
	if index > 0 {
		if !strings.HasSuffix(info, ":") {
			return nil, fmt.Errorf("invalid line: %s, because file info must end with ':'", line)
		}
		info = info[:len(info)-1]
		if info == "" {
			return nil, fmt.Errorf("invalid line: %s, because file name can't be empty", line)
		}
		infoParts := strings.Split(info, ":")
		node.Name = infoParts[0]
		if len(infoParts) > 1 {
			size, err := strconv.ParseInt(infoParts[1], 10, 64)
			if err != nil {
				return nil, fmt.Errorf("invalid line: %s, because file size must be an integer", line)
			}
			node.Size = size
			haveSize = true
			if len(infoParts) > 2 {
				modified, err := strconv.ParseInt(infoParts[2], 10, 64)
				if err != nil {
					return nil, fmt.Errorf("invalid line: %s, because file modified must be an unix timestamp", line)

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Format file lines strictly as Name:Size:Modified:URL with colons separating each metadata field.
  2. Omit metadata entirely (bare URL) — the node name then defaults to stdpath.Base(url).
  3. Double-check the last metadata field before the URL still ends with ':'.

Example fix

// before
movie.mp4 1024 https://x/m.mp4

// after
movie.mp4:1024: https://x/m.mp4
Defensive patterns

Strategy: validation

Validate before calling

func validateFileLine(line string) error {
    idx := strings.Index(line, "http://")
    if idx == -1 { idx = strings.Index(line, "https://") }
    if idx <= 0 { return nil } // bare URL or missing URL handled elsewhere
    if !strings.HasSuffix(line[:idx], ":") {
        return fmt.Errorf("metadata must end with ':' before URL")
    }
    return nil
}

Try / catch

if err != nil && strings.Contains(err.Error(), "must end with ':'") { /* convert space separators to colons in the echoed line */ }

Prevention

When it happens

Trigger: Lines like 'name size https://...' (space separators) or 'name:1024 https://...' — any prefix that does not end with ':' right where the URL begins.

Common situations: Writing the structure with spaces instead of colons, or deleting the trailing colon while editing sizes/timestamps. Caught at BuildTree during Init.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/b0010a8c7f92bfd2. Report an issue: GitHub.