{"record":{"id":"de5db8057720eeef","repo":"AlistGo/alist","slug":"invalid-download-params-q-w","errorCode":null,"errorMessage":"invalid download_params %q: %w","messagePattern":"invalid download_params %q: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/url_tree/driver.go","lineNumber":129,"sourceCode":"\terr := d.downloadParamsTmpl.Execute(&sb, map[string]interface{}{\n\t\t\"Name\":     node.Name,\n\t\t\"Path\":     path,\n\t\t\"Size\":     node.Size,\n\t\t\"Modified\": node.Modified,\n\t})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to render download_params: %w\", err)\n\t}\n\trendered := strings.TrimSpace(sb.String())\n\trendered = strings.TrimPrefix(rendered, \"?\")\n\tif rendered == \"\" {\n\t\treturn node.Url, nil\n\t}\n\t// Parse the rendered string so that magic-variable values (e.g. file names\n\t// with non-ASCII characters) are properly URL-encoded by Encode().\n\tquery, err := url.ParseQuery(rendered)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid download_params %q: %w\", rendered, err)\n\t}\n\treturn utils.InjectQuery(node.Url, query)\n}\n\nfunc (d *Urls) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) {\n\tif !d.Writable {\n\t\treturn nil, errs.PermissionDenied\n\t}\n\td.mutex.Lock()\n\tdefer d.mutex.Unlock()\n\tnode := GetNodeFromRootByPath(d.root, parentDir.GetPath())\n\tif node == nil {\n\t\treturn nil, errs.ObjectNotFound\n\t}\n\tif node.isFile() {\n\t\treturn nil, errs.NotFolder\n\t}\n\tdir := &Node{","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/url_tree/driver.go#L111-L147","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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 '?'."],"exampleFix":"// before\ndownload_params = \"?token=abc&{{.Name}}\"\n\n// after\ndownload_params = \"token=abc&file={{.Name}}\"","handlingStrategy":"validation","validationCode":"func validateRenderedParams(rendered string) error {\n    rendered = strings.TrimPrefix(strings.TrimSpace(rendered), \"?\")\n    if rendered == \"\" { return nil }\n    _, err := url.ParseQuery(rendered)\n    return err\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"invalid download_params\") {\n    // message includes %q of rendered string; fix template accordingly\n}","preventionTips":["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"],"tags":["url-tree","query-string","template","validation"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}