grafana/k6 · error
invalid reflectMetadata param: %w
Error message
invalid reflectMetadata param: %w
What it means
reflectMetadata in client.connect() params is parsed by the same newMetadata() used for call metadata: it must be a plain object of string values (plus Uint8Array/ArrayBuffer for -bin keys) that k6 attaches to reflection requests. Any other shape or value type is wrapped as 'invalid reflectMetadata param'.
Source
Thrown at internal/js/modules/k6/grpc/params.go:180
if !ok {
return result, fmt.Errorf("invalid plaintext value: '%#v', it needs to be boolean", v)
}
case "timeout":
var err error
result.Timeout, err = types.GetDurationValue(v)
if err != nil {
return result, fmt.Errorf("invalid timeout value: %w", err)
}
case "reflect":
var ok bool
result.UseReflectionProtocol, ok = v.(bool)
if !ok {
return result, fmt.Errorf("invalid reflect value: '%#v', it needs to be boolean", v)
}
case "reflectMetadata":
md, err := newMetadata(params.Get(k))
if err != nil {
return result, fmt.Errorf("invalid reflectMetadata param: %w", err)
}
result.ReflectionMetadata = md
case "maxReceiveSize":
var ok bool
result.MaxReceiveSize, ok = v.(int64)
if !ok {
return result, fmt.Errorf("invalid maxReceiveSize value: '%#v', it needs to be an integer", v)
}
if result.MaxReceiveSize < 0 {
return result, fmt.Errorf("invalid maxReceiveSize value: '%#v, it needs to be a positive integer", v)
}
case "maxSendSize":
var ok bool
result.MaxSendSize, ok = v.(int64)
if !ok {
return result, fmt.Errorf("invalid maxSendSize value: '%#v', it needs to be an integer", v)
}View on GitHub (pinned to 93accf6570)
Solutions
- Pass a plain object: reflectMetadata: { auth: 'token' }
- Apply the same rules as call metadata: strings for normal keys, Uint8Array for -bin keys
- Read the wrapped cause after the colon in the message to find the offending key
Example fix
// before
client.connect(addr, { reflect: true, reflectMetadata: 'auth=token' });
// after
client.connect(addr, { reflect: true, reflectMetadata: { auth: 'token' } }); Defensive patterns
Strategy: validation
Validate before calling
if (connectParams.reflectMetadata != null) {
assertGrpcMetadata(connectParams.reflectMetadata, 'reflectMetadata');
}
client.connect(addr, connectParams); Type guard
function isPlainObject(v) {
return v != null && typeof v === 'object' && !Array.isArray(v);
} Prevention
- Pass reflectMetadata as a plain object of string values, same rules as call metadata
- Use Uint8Array for any -bin keys inside reflectMetadata
- Do not pass grpcurl-style 'k=v' header strings
When it happens
Trigger: connect(addr, { reflect: true, reflectMetadata: 'auth=token' }) (string, not object); { reflectMetadata: { 'trace-bin': 'xyz' } }; { reflectMetadata: ['auth'] }.
Common situations: Passing grpcurl-style header strings; reusing header arrays from other clients; forgetting the string/binary value rules apply here too.
Related errors
- invalid reflect value: '%#v', it needs to be boolean
- invalid metadata param: %w
- %q value must be binary
- %q value must be a string
- invalid plaintext value: '%#v', it needs to be boolean
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/8d3e9cb885d7a0f8.
Report an issue: GitHub.