grafana/k6 · error
format of value must be k=v, received %q
Error message
format of value must be k=v, received %q
What it means
A single comma-separated segment of K6_BROWSER_SCREENSHOTS_OUTPUT does not contain exactly one '=' (file_persister.go:52). The parser splits each segment on '=' and requires exactly two parts, so segments with zero '=' or with more than one '=' are rejected.
Source
Thrown at internal/js/modules/k6/browser/browser/file_persister.go:52
}
// parsePresignedURLEnvVar will parse a value such as:
// url=https://127.0.0.1/,basePath=/screenshots,header.1=a,header.2=b
// and return them.
//
func parsePresignedURLEnvVar(envVarValue string) (presignedURLConfig, error) {
ss := strings.Split(envVarValue, ",")
presignedURL := presignedURLConfig{
headers: make(map[string]string),
}
for _, s := range ss {
// The key value pair should be of the form key=value, so split
// on '=' to retrieve the key and value separately.
kv := strings.Split(s, "=")
if len(kv) != 2 {
return presignedURLConfig{}, fmt.Errorf("format of value must be k=v, received %q", s)
}
k := kv[0]
v := kv[1]
// A key with "header." means that the header name is encoded in the
// key, separated by a ".". Split the header on "." to retrieve the
// header name. The header value should be present in v from the previous
// split.
var hv, hk string
if strings.Contains(k, "header.") {
hv = v
hh := strings.Split(k, ".")
if len(hh) != 2 {
return presignedURLConfig{}, fmt.Errorf("format of header must be header.k=v, received %q", s)
}
View on GitHub (pinned to 93accf6570)
Solutions
- Ensure every comma-separated segment has exactly one '='; remove trailing/leading commas
- URL-encode '=' inside values as %3D and ',' as %2C
- If the presigned URL cannot be encoded cleanly, put the signed query into a header.* entry instead of the url value
- Validate the value with a one-liner before launching k6: echo "$V" | tr ',' '\n' | awk -F= 'NF!=2{print "bad segment: "$0; exit 1}'
Example fix
# before K6_BROWSER_SCREENSHOTS_OUTPUT="url=https://h/?sig=abc,basePath=/s" # after K6_BROWSER_SCREENSHOTS_OUTPUT="url=https://h/?sig%3Dabc,basePath=/s"
Defensive patterns
Strategy: validation
Validate before calling
// Node/JS pre-check
function segmentsOk(v) {
return v.split(',').every(s => (s.match(/=/g) || []).length === 1 && s.trim().length > 0);
}
if (!segmentsOk(process.env.K6_BROWSER_SCREENSHOTS_OUTPUT || '')) {
throw new Error('K6_BROWSER_SCREENSHOTS_OUTPUT: every segment must be exactly k=v');
} Prevention
- Never paste presigned URLs with raw query strings into the env var - encode or move auth to headers
- Avoid trailing commas and empty segments
- Add the one-line awk/tr check to CI before k6 runs
When it happens
Trigger: K6_BROWSER_SCREENSHOTS_OUTPUT contains a trailing comma ('url=https://h/,', empty last segment), a bare token without '=' ('strict'), or a URL whose query string itself contains '=' ('url=https://h/?X-Amz-Signature=abc' splits into three parts).
Common situations: Pasting a presigned S3/Azure URL with signature query parameters into the env var; YAML/CI env files that strip quotes; values copied from documentation examples where the '=' inside the value went unencoded.
Related errors
- invalid option %q
- parsing %s: %w
- format of header must be header.k=v, received %q
- empty header key, received %q
- invalid url %q
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/2fda3f96838f9ca9.
Report an issue: GitHub.