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

  1. Inspect the quoted rendered string in the message and fix the template so output is strictly key=value&key=value.
  2. Quote/encode magic variables, e.g. use {{.Name}} only as a full value after '=', never embed raw inside a key or separator position.
  3. 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

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


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