grafana/k6 · error
failed to parse template file %s: %w
Error message
failed to parse template file %s: %w
What it means
The template file was read successfully but its content is not valid Go text/template syntax (template.New(...).Parse failed). k6 templates use Go template actions with fields like {{.ScriptName}} and {{.ProjectID}}; malformed actions (unclosed {{, missing {{end}}) or JS-style placeholders without the leading dot produce a parse error wrapped as "failed to parse template file <tpl>".
Source
Thrown at internal/cmd/templates/templates.go:92
return tm.browserTemplate, nil
}
// Then check if it's a file path
if isFilePath(tpl) {
tplPath, err := filepath.Abs(tpl)
if err != nil {
return nil, fmt.Errorf("failed to get absolute path for template %s: %w", tpl, err)
}
// Read the template content using the provided filesystem
content, err := fsext.ReadFile(tm.fs, tplPath)
if err != nil {
return nil, fmt.Errorf("failed to read template file %s: %w", tpl, err)
}
tmpl, err := template.New(filepath.Base(tplPath)).Parse(string(content))
if err != nil {
return nil, fmt.Errorf("failed to parse template file %s: %w", tpl, err)
}
return tmpl, nil
}
// Check if there's a file with this name in current directory
exists, err := fsext.Exists(tm.fs, fsext.JoinFilePath(".", tpl))
if err == nil && exists {
return nil, fmt.Errorf("invalid template type %q, did you mean ./%s?", tpl, tpl)
}
return nil, fmt.Errorf("invalid template type %q", tpl)
}
// isFilePath checks if the given string looks like a file path by detecting path separators
// We assume that built-in template names don't contain path separators
func isFilePath(path string) bool {
return strings.ContainsRune(path, filepath.Separator) || strings.ContainsRune(path, '/')View on GitHub (pinned to 93accf6570)
Solutions
- Fix the Go template grammar: every action is {{ ... }} and each {{if}}/{{range}} needs a matching {{end}}
- Reference built-in fields with the leading dot: {{.ScriptName}}, {{.ProjectID}}
- Start from a working built-in template (minimal, protocol, browser) and change one thing at a time
- Escape literal '{{' in JS with {{"{{"}} if the output must contain it
Example fix
// before
export default function () { console.log('{{ScriptName}}'); }
// after
export default function () { console.log('{{.ScriptName}}'); } Defensive patterns
Strategy: validation
Validate before calling
// dryparse.go — verify a k6 template parses before using it: go run dryparse.go tpl.js
package main
import (
"os"
"text/template"
)
func main() {
b, err := os.ReadFile(os.Args[1])
if err != nil {
panic(err)
}
if _, err := template.New("t").Parse(string(b)); err != nil {
panic(err)
}
} Prevention
- Start from built-in templates and edit incrementally
- Always use the leading dot for fields: {{.ScriptName}}, {{.ProjectID}}
- Close every {{if}}/{{range}} with {{end}}
- Add a text/template parse step to CI for custom templates
When it happens
Trigger: A template containing '{{.ScriptName' (unclosed action), '{{if .X}}' without '{{end}}', or '{{ScriptName}}' (missing dot, invalid in Go template syntax).
Common situations: Converting Mustache/Handlebars JS templates to k6's Go-template format; hand-editing generated templates and breaking delimiters; brace-heavy JS code accidentally containing {{ sequences.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- error initializing template manager: %w
- error retrieving template: %w
- failed to execute template %s: %w
- error for stage %d: %w
- failed to get absolute path for template %s: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/a558e59be6e18877.
Report an issue: GitHub.