grafana/k6 · error
invalid GRPC Stream's parameters: %w
Error message
invalid GRPC Stream's parameters: %w
What it means
The optional third argument of new grpc.Stream(client, method, params) is validated by newCallParams(), which accepts only four keys: metadata, tags, timeout and discardResponseMessage. Any failure inside that validation (bad metadata object, non-scalar tag value, unparseable timeout, unknown key) is wrapped and rethrown as "invalid GRPC Stream's parameters".
Source
Thrown at internal/js/modules/k6/grpc/grpc.go:128
// stream returns a new stream object
func (mi *ModuleInstance) stream(c sobek.ConstructorCall) *sobek.Object {
rt := mi.vu.Runtime()
client, err := extractClient(c.Argument(0), rt)
if err != nil {
common.Throw(rt, fmt.Errorf("invalid GRPC Stream's client: %w", err))
}
methodName := sanitizeMethodName(c.Argument(1).String())
methodDescriptor, err := client.getMethodDescriptor(methodName)
if err != nil {
common.Throw(rt, fmt.Errorf("invalid GRPC Stream's method: %w", err))
}
p, err := newCallParams(mi.vu, c.Argument(2))
if err != nil {
common.Throw(rt, fmt.Errorf("invalid GRPC Stream's parameters: %w", err))
}
p.SetSystemTags(mi.vu.State(), client.addr, methodName)
logger := mi.vu.State().Logger.WithField("streamMethod", methodName)
s := &stream{
vu: mi.vu,
client: client,
methodDescriptor: methodDescriptor,
method: methodName,
logger: logger,
tq: taskqueue.New(mi.vu.RegisterCallback),
instanceMetrics: mi.metrics,
builtinMetrics: mi.vu.State().BuiltinMetrics,
done: make(chan struct{}),View on GitHub (pinned to 93accf6570)
Solutions
- Read the wrapped cause after the colon in the message; it names the exact offending key and expected type
- Keep only metadata, tags, timeout and discardResponseMessage in the object
- Validate the params object with a helper before passing it (see defense)
Example fix
// before
const stream = new grpc.Stream(client, METHOD, { headers: { 'x-tag': 'v' } });
// after
const stream = new grpc.Stream(client, METHOD, { metadata: { 'x-tag': 'v' } }); Defensive patterns
Strategy: validation
Validate before calling
const CALL_PARAM_KEYS = new Set(['metadata', 'tags', 'timeout', 'discardResponseMessage']);
function assertCallParams(p) {
if (p == null) return;
for (const k of Object.keys(p)) {
if (!CALL_PARAM_KEYS.has(k)) throw new Error(`unknown grpc param '${k}'`);
}
if (p.timeout != null && !isDurationValue(p.timeout)) throw new Error('invalid timeout');
if (p.metadata != null) assertGrpcMetadata(p.metadata);
}
assertCallParams(params);
const stream = new grpc.Stream(client, METHOD, params); Prevention
- Build grpc params objects from scratch instead of reusing HTTP options objects
- Centralize params construction in one helper so validation runs in one place
- Log the wrapped cause whenever a params error is caught
When it happens
Trigger: new grpc.Stream(client, method, { headers: {...} }) (unknown key); { metadata: { 'x-bin': 'text' } } (binary key with a string value); { timeout: 'soon' }; { tags: { user: {} } }.
Common situations: Reusing a params object built for client.invoke() that carries extra keys; sharing an HTTP-flavoured options helper across protocols; key names drifting between k6 versions.
Related errors
- unknown param: %q
- method to invoke cannot be empty
- request cannot be nil
- empty gRPC client
- no gRPC connection, you must call connect first
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/0a3ae3fcfd823586.
Report an issue: GitHub.