grafana/k6 · error

method %q not found in file descriptors

Error message

method %q not found in file descriptors

What it means

client.invoke() looks up the method name (auto-prefixed with '/' if missing) in the descriptor map built only by client.load() or connect(reflect: true); a miss yields 'method %q not found in file descriptors' (internal/js/modules/k6/grpc/client.go:366). The connection is fine - the method simply was never registered: wrong fully-qualified name, or the loaded descriptors do not contain that service.

Source

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

) (grpcext.InvokeRequest, error) {
	grpcReq := grpcext.InvokeRequest{}

	state := c.vu.State()
	if state == nil {
		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())

View on GitHub (pinned to 93accf6570)

Solutions

  1. client.load() returns the parsed methods - log it and copy the exact FullMethod ('/package.Service/Method') into invoke
  2. Regenerate the protoset including imports: protoc --include_imports --descriptor_set_out=...
  3. Or connect with reflect: true to register the server's live method list

Example fix

// before
client.invoke('users.User/GetUser'); // wrong package

// after
const methods = client.load('./pb/service.protoset');
console.log(JSON.stringify(methods.map(m => m.FullMethod))); // copy exact name
client.invoke('/myapp.users.UserService/GetUser');
Defensive patterns

Strategy: validation

Validate before calling

const methods = client.load('./pb/service.protoset');
const known = new Set(methods.map(m => m.FullMethod));
function invokeKnown(method, req, params) {
  const full = method.startsWith('/') ? method : '/' + method;
  if (!known.has(full)) throw new Error(`unknown method ${full}; known: ${[...known].join(', ')}`);
  return client.invoke(full, req, params);
}

Try / catch

try { client.invoke(m, req); } catch (e) { if (/not found in file descriptors/.test(e.message)) { /* log the load() result and fix the method name; not retryable as-is */ } throw e; }

Prevention

When it happens

Trigger: client.invoke('myapp.Users/GetUser') with wrong package, service, or method casing; a protoset built without --include_imports so the service's proto is missing; calling invoke on a client that never called load() and connected without reflect.

Common situations: Protobuf package names differing from directory names; protosets generated from the wrong .proto file; methods renamed server-side after the protoset was generated; examples copied from other projects with different package names.

Related errors


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