AlistGo/alist · error
failed to render download_params: %w
Error message
failed to render download_params: %w
What it means
While building a download link, the url_tree driver executes the previously parsed download_params template with the node's magic variables (Name, Path, Size, Modified). Execution fails if the template references a field that is not provided or a function errors at runtime; the error is wrapped and the Link call fails for that file.
Source
Thrown at drivers/url_tree/driver.go:118
return &model.Link{
URL: downURL,
}, nil
}
return nil, errs.NotFile
}
// buildDownloadURL renders the configured download_params template with the
// node's magic variables and appends the result as query parameters to the URL.
func (d *Urls) buildDownloadURL(node *Node, path string) (string, error) {
var sb strings.Builder
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.PermissionDeniedView on GitHub (pinned to 843d9dc814)
Solutions
- Restrict template fields to exactly Name, Path, Size, Modified; fix typos such as {{.Filename}} -> {{.Name}}.
- Test the template with dummy values mirroring those four keys to confirm it renders.
- Simplify: remove custom template functions; text/template built-ins only are supported.
Example fix
// before
download_params = "fname={{.Filename}}"
// after
download_params = "fname={{.Name}}" Defensive patterns
Strategy: validation
Validate before calling
var allowedFields = map[string]bool{"Name": true, "Path": true, "Size": true, "Modified": true}
// after parsing, walk template.Tree and reject .Field lookups not in allowedFields
func checkFields(t *template.Template) error {
_, err := t.Execute(nil, map[string]any{"Name": "x", "Path": "/x", "Size": int64(1), "Modified": int64(0)})
return err // nil map input still executes field lookups; use dummy values
} Try / catch
url, err := d.buildDownloadURL(node, path)
if err != nil && strings.Contains(err.Error(), "failed to render") {
// log node identity and template; fall back to raw node.Url if acceptable
} Prevention
- Test template execution with dummy values for all four variables before deploying
- Never reference fields outside Name/Path/Size/Modified
- Log the failing node to identify which file's data broke rendering
When it happens
Trigger: A template that parsed fine but references {{.Missing}} (nil field) or uses functions that error during Execute when called from buildDownloadURL for a specific node/path.
Common situations: Typo in a field name like {{.Filename}} instead of {{.Name}}, or expecting per-node fields that the driver does not inject. Storage initializes fine but every download fails.
Related errors
- failed to parse download_params: %w
- invalid download_params %q: %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/c045431f2eee5943.
Report an issue: GitHub.