grafana/k6 · error

invalid GRPC's client.invoke() parameters: %w

Error message

invalid GRPC's client.invoke() parameters: %w

What it means

The third argument of client.invoke() (also used by new grpc.Stream) is validated by newCallParams; failures are wrapped as "invalid GRPC's client.invoke() parameters: <cause>" (internal/js/modules/k6/grpc/client.go:371). Causes: 'unknown param: <key>' (allowed keys are metadata, tags, timeout, discardResponseMessage), 'invalid metadata param' (metadata must be an object; non '-bin' values must be strings, '-bin' keys need binary values), 'metric tags', or 'invalid timeout value' (duration string or millisecond number).

Source

Thrown at internal/js/modules/k6/grpc/client.go:371

		return grpcReq, common.NewInitContextError("invoking RPC methods in the init context is not supported")
	}
	if c.conn == nil {
		return grpcReq, errors.New("no gRPC connection, you must call connect first")
	}
	if method == "" {
		return grpcReq, errors.New("method to invoke cannot be empty")
	}
	if method[0] != '/' {
		method = "/" + method
	}
	methodDesc := c.mds[method]
	if methodDesc == nil {
		return grpcReq, fmt.Errorf("method %q not found in file descriptors", method)
	}

	p, err := newCallParams(c.vu, params)
	if err != nil {
		return grpcReq, fmt.Errorf("invalid GRPC's client.invoke() parameters: %w", err)
	}

	// k6 GRPC Invoke's default timeout is 2 minutes
	if p.Timeout == time.Duration(0) {
		p.Timeout = 2 * time.Minute
	}

	if req == nil {
		return grpcReq, errors.New("request cannot be nil")
	}

	object := req.ToObject(c.vu.Runtime())

	var stack []*sobek.Object
	normalized, err := normalizeNumberStrings(object, c.vu.Runtime(), stack)
	if err != nil {
		return grpcReq, fmt.Errorf("unable to normalize number strings: %w", err)
	}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Fix the wrapped cause: correct the key name, stringify metadata values, use duration strings like '500ms'
  2. Keep only metadata, tags, timeout, discardResponseMessage in invoke params
  3. For binary metadata use keys ending in -bin with byte values (e.g. from k6/encoding)

Example fix

// before
client.invoke(method, req, { metadata: { 'x-count': 5 } });

// after
client.invoke(method, req, { metadata: { 'x-count': String(5) } });
Defensive patterns

Strategy: validation

Validate before calling

const CALL_KEYS = new Set(['metadata','tags','timeout','discardResponseMessage']);
function assertCallParams(p = {}) {
  for (const k of Object.keys(p)) {
    if (!CALL_KEYS.has(k)) throw new Error(`unknown invoke param: ${k}`);
  }
  for (const [k, v] of Object.entries(p.metadata || {})) {
    if (!k.endsWith('-bin') && typeof v !== 'string') throw new Error(`metadata[${k}] must be a string`);
  }
  return p;
}
client.invoke(method, req, assertCallParams(params));

Try / catch

try { client.invoke(m, req, params); } catch (e) { if (/invalid GRPC's client.invoke\(\) parameters/.test(e.message)) { /* wrapped cause names the bad key/value; fix and retry */ } throw e; }

Prevention

When it happens

Trigger: client.invoke(m, req, { metada: {...} }) (typo -> unknown param); client.invoke(m, req, { metadata: { 'x-count': 5 } }) (number instead of string); client.invoke(m, req, { timeout: '10 seconds' }) (unparseable duration).

Common situations: Passing numeric metadata values straight from JS variables without String(); assuming the HTTP module's option formats apply; typo'd keys in large param objects.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/ddd66a082f8ed3cb. Report an issue: GitHub.