{"record":{"id":"a66ce098d70fe313","repo":"AlistGo/alist","slug":"failed-to-parse-download-params-w","errorCode":null,"errorMessage":"failed to parse download_params: %w","messagePattern":"failed to parse download_params: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/url_tree/driver.go","lineNumber":48,"sourceCode":"\treturn config\n}\n\nfunc (d *Urls) GetAddition() driver.Additional {\n\treturn &d.Addition\n}\n\nfunc (d *Urls) Init(ctx context.Context) error {\n\tnode, err := BuildTree(d.UrlStructure, d.HeadSize)\n\tif err != nil {\n\t\treturn err\n\t}\n\tnode.calSize()\n\td.root = node\n\td.downloadParamsTmpl = nil\n\tif params := strings.TrimSpace(d.DownloadParams); params != \"\" {\n\t\ttmpl, err := template.New(\"downloadParams\").Parse(params)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to parse download_params: %w\", err)\n\t\t}\n\t\td.downloadParamsTmpl = tmpl\n\t}\n\treturn nil\n}\n\nfunc (d *Urls) Drop(ctx context.Context) error {\n\treturn nil\n}\n\nfunc (d *Urls) Get(ctx context.Context, path string) (model.Obj, error) {\n\td.mutex.RLock()\n\tdefer d.mutex.RUnlock()\n\tnode := GetNodeFromRootByPath(d.root, path)\n\treturn nodeToObj(node, path)\n}\n\nfunc (d *Urls) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/url_tree/driver.go#L30-L66","documentation":"The url_tree driver parses the optional download_params mount option as a Go text/template at Init time. If the string is not valid template syntax, template.New(...).Parse fails and Init aborts with this wrapped error, so the storage is never registered.","triggerScenarios":"Configuring a url_tree storage whose download_params contains invalid template syntax — unclosed {{ , unknown functions, stray {{end}}, or unmatched delimiters.","commonSituations":"Copy-pasting a template with smart quotes, forgetting the pipe on {{.Name | urlquery}}, using a function that does not exist in text/template, or trailing '{{'. Fails at storage-add time, not at download time.","solutions":["Fix the template syntax in download_params; valid magic variables are Name, Path, Size, Modified (e.g. \"token=xxx&name={{.Name}}\").","Validate the template locally with Go or an online text/template checker before saving the storage config.","Leave download_params empty if no extra query parameters are needed — empty is skipped entirely."],"exampleFix":"// before (invalid: unclosed action)\ndownload_params = \"token=abc&file={{.Name\"\n\n// after\ndownload_params = \"token=abc&file={{.Name}}\"","handlingStrategy":"validation","validationCode":"func validateDownloadParams(params string) error {\n    if strings.TrimSpace(params) == \"\" { return nil }\n    _, err := template.New(\"downloadParams\").Parse(params)\n    return err // surface before saving storage config\n}","typeGuard":null,"tryCatchPattern":"if err := storage.Init(ctx); err != nil && strings.Contains(err.Error(), \"failed to parse download_params\") {\n    // show template syntax error to user editing the storage config\n}","preventionTips":["Dry-run template.New(...).Parse in a config lint step","Use only text/template built-ins and the four magic variables","Keep templates one-line and simple"],"tags":["url-tree","template","config","validation"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}