AlistGo/alist · error
invalid download_params %q: %w
Error message
invalid download_params %q: %w
What it means
After rendering download_params, the driver strips a leading '?' and runs url.ParseQuery over the result so values get properly URL-encoded before being injected into the file URL. If the rendered string is not a valid query string (e.g. contains a bare '&' or '=' structure that cannot parse), ParseQuery fails and this wrapped error includes the offending rendered text.
Source
Thrown at drivers/url_tree/driver.go:129
err := d.downloadParamsTmpl.Execute(&sb, map[string]interface{}{
"Name": node.Name,
"Path": path,
"Size": node.Size,
"Modified": node.Modified,
})
if err != nil {
return "", fmt.Errorf("failed to render download_params: %w", err)
}
rendered := strings.TrimSpace(sb.String())
rendered = strings.TrimPrefix(rendered, "?")
if rendered == "" {
return node.Url, nil
}
// Parse the rendered string so that magic-variable values (e.g. file names
// with non-ASCII characters) are properly URL-encoded by Encode().
query, err := url.ParseQuery(rendered)
if err != nil {
return "", fmt.Errorf("invalid download_params %q: %w", rendered, err)
}
return utils.InjectQuery(node.Url, query)
}
func (d *Urls) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) {
if !d.Writable {
return nil, errs.PermissionDenied
}
d.mutex.Lock()
defer d.mutex.Unlock()
node := GetNodeFromRootByPath(d.root, parentDir.GetPath())
if node == nil {
return nil, errs.ObjectNotFound
}
if node.isFile() {
return nil, errs.NotFolder
}
dir := &Node{View on GitHub (pinned to 843d9dc814)
Solutions
- Inspect the quoted rendered string in the message and fix the template so output is strictly key=value&key=value.
- Quote/encode magic variables, e.g. use {{.Name}} only as a full value after '=', never embed raw inside a key or separator position.
- Remove decorative characters ('?', spaces, newlines) from the template; the driver already trims whitespace and one leading '?'.
Example fix
// before
download_params = "?token=abc&{{.Name}}"
// after
download_params = "token=abc&file={{.Name}}" Defensive patterns
Strategy: validation
Validate before calling
func validateRenderedParams(rendered string) error {
rendered = strings.TrimPrefix(strings.TrimSpace(rendered), "?")
if rendered == "" { return nil }
_, err := url.ParseQuery(rendered)
return err
} Try / catch
if err != nil && strings.Contains(err.Error(), "invalid download_params") {
// message includes %q of rendered string; fix template accordingly
} Prevention
- Render templates as strict key=value&key=value output
- Never place separators or '?' inside the template body
- URL-encode values produced by magic variables by keeping them as whole values
When it happens
Trigger: download_params renders to something like "a=1&&b=" (empty key/invalid pairs), contains a lone ';' or unencodable control characters, or the magic-variable expansion produces text that breaks key=value structure (e.g. a Name containing '=' or '&' unencoded in the middle of a value that also lacks proper pairing).
Common situations: Templates that emit raw separators, or values with special characters. Init succeeds; only MakeLink/download fails, and %q in the message shows exactly what was rendered.
Related errors
- failed to parse download_params: %w
- failed to render download_params: %w
- the line '%s' is not a multiple of 2
- invalid line: %s, because url is required for file
- invalid line: %s, because file info must end with ':'
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/de5db8057720eeef.
Report an issue: GitHub.