grafana/k6 · error
%q value must be a string
Error message
%q value must be a string
What it means
Metadata keys that do not end in -bin must map to string values; newMetadata asserts the exported JS value is a Go string (params.go:99). Numbers, booleans, objects, arrays or null on a normal key throw '%q value must be a string'.
Source
Thrown at internal/js/modules/k6/grpc/params.go:100
rawHeaders, ok := v.(map[string]any)
if !ok {
return md, errors.New("must be an object with key-value pairs")
}
for hk, kv := range rawHeaders {
var val string
// The gRPC spec defines that Binary-valued keys end in -bin
// https://grpc.io/docs/what-is-grpc/core-concepts/#metadata
if strings.HasSuffix(hk, "-bin") {
var binVal []byte
if binVal, ok = kv.([]byte); !ok {
return md, fmt.Errorf("%q value must be binary", hk)
}
// https://github.com/grpc/grpc-go/blob/v1.57.0/Documentation/grpc-metadata.md#storing-binary-data-in-metadata
val = string(binVal)
} else if val, ok = kv.(string); !ok {
return md, fmt.Errorf("%q value must be a string", hk)
}
md.Append(hk, val)
}
return md, nil
}
// SetSystemTags sets the system tags for the call.
func (p *callParams) SetSystemTags(state *lib.State, addr string, methodName string) {
if state.Options.SystemTags.Has(metrics.TagURL) {
p.TagsAndMeta.SetSystemTagOrMeta(metrics.TagURL, fmt.Sprintf("%s%s", addr, methodName))
}
parts := strings.Split(methodName[1:], "/")
p.TagsAndMeta.SetSystemTagOrMetaIfEnabled(state.Options.SystemTags, metrics.TagService, parts[0])
p.TagsAndMeta.SetSystemTagOrMetaIfEnabled(state.Options.SystemTags, metrics.TagMethod, parts[1])
View on GitHub (pinned to 93accf6570)
Solutions
- Stringify scalars: String(42), String(true)
- For genuinely binary data, rename the key with a -bin suffix and pass a Uint8Array
Example fix
// before
{ metadata: { 'x-user-id': 42 } }
// after
{ metadata: { 'x-user-id': '42' } } Defensive patterns
Strategy: type-guard
Validate before calling
for (const [k, v] of Object.entries(params.metadata || {})) {
if (!k.endsWith('-bin') && typeof v !== 'string') {
throw new Error(`metadata['${k}'] must be a string, got ${typeof v}`);
}
}
client.invoke(method, req, params); Type guard
function isStringMetadataValue(key, v) {
return key.endsWith('-bin') ? v instanceof Uint8Array : typeof v === 'string';
} Prevention
- Stringify numbers and booleans before adding them to metadata
- If a value is genuinely binary, rename the key with a -bin suffix and use a Uint8Array
- Avoid spreading untyped JSON payloads into metadata
When it happens
Trigger: { 'x-user-id': 42 }; { active: true }; { user: { id: 1 } }; { ref: null }.
Common situations: Sending numeric IDs or flags as metadata without stringifying; spreading parsed JSON directly into metadata objects.
Related errors
- invalid metadata param: %w
- %q value must be binary
- invalid reflectMetadata param: %w
- Unexpected end of selector while parsing selector `${selecto
- must be an object with key-value pairs
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/9ad31b3337246878.
Report an issue: GitHub.