AlistGo/alist · error
the line '%s' is not a multiple of 2
Error message
the line '%s' is not a multiple of 2
What it means
The url_tree driver builds a file hierarchy from an indented text structure where each nesting level is exactly two spaces. When a line's leading-space count is odd (indent%2 != 0), the tree parser cannot compute a level and aborts tree construction with this per-line error.
Source
Thrown at drivers/url_tree/util.go:51
* url8
*/
// if there are no name, use the last segment of url as name
func BuildTree(text string, headSize bool) (*Node, error) {
lines := strings.Split(text, "\n")
var root = &Node{Level: -1, Name: "root"}
stack := []*Node{root}
for _, line := range lines {
// calculate indent
indent := 0
for i := 0; i < len(line); i++ {
if line[i] != ' ' {
break
}
indent++
}
// if indent is not a multiple of 2, it is an error
if indent%2 != 0 {
return nil, fmt.Errorf("the line '%s' is not a multiple of 2", line)
}
// calculate level
level := indent / 2
line = strings.TrimSpace(line[indent:])
// if the line is empty, skip
if line == "" {
continue
}
// if level isn't greater than the level of the top of the stack
// it is not the child of the top of the stack
for level <= stack[len(stack)-1].Level {
// pop the top of the stack
stack = stack[:len(stack)-1]
}
// if the line is a folder
if isFolder(line) {
// create a new node
node := &Node{View on GitHub (pinned to 843d9dc814)
Solutions
- Re-indent the whole url_structure using only multiples of two spaces per level (0, 2, 4, 6 ...).
- Replace all tabs with spaces in the config before saving.
- Re-generate the structure with StringifyTree output as a canonical reference — it always emits two spaces per level.
Example fix
// before root: a.txt http://x/a b.txt http://x/b // 3 spaces -> error // after root: a.txt http://x/a b.txt http://x/b
Defensive patterns
Strategy: validation
Validate before calling
func validateIndentation(structure string) error {
for _, line := range strings.Split(structure, "\n") {
indent := 0
for indent < len(line) && line[indent] == ' ' { indent++ }
if indent%2 != 0 {
return fmt.Errorf("line %q has odd indent", line)
}
}
return nil
} Try / catch
if _, err := BuildTree(structure, headSize); err != nil {
if strings.Contains(err.Error(), "not a multiple of 2") { /* fix indentation in config */ }
return err
} Prevention
- Use exactly two spaces per nesting level
- Expand tabs to spaces before pasting into url_structure
- Round-trip via StringifyTree to normalize formatting
When it happens
Trigger: Any line in the url_structure config whose indentation is 1, 3, 5, ... spaces — e.g. a tab converted partially, or manual alignment with an odd number of spaces.
Common situations: Copy-pasting tree text from editors with tab expansion, mixing tabs and spaces, or hand-editing the structure and adding a stray space. Fails at storage Init, so the mount is rejected outright.
Related errors
- failed to parse download_params: %w
- invalid line: %s, because url is required for file
- invalid line: %s, because file info must end with ':'
- invalid line: %s, because file name can't be empty
- invalid line: %s, because file size must be an integer
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/0c944111788c5540.
Report an issue: GitHub.