grafana/k6 · error
no gRPC connection, you must call connect first
Error message
no gRPC connection, you must call connect first
What it means
After a `grpc.Client` is created, its internal `conn` field is nil until `connect()` succeeds (and `close()` resets it to nil). extractClient (internal/js/modules/k6/grpc/grpc.go:179) rejects such a disconnected client with "no gRPC connection, you must call connect first" when it is passed to `new grpc.Stream(client, ...)`. It means you have a valid Client object that has no live connection.
Source
Thrown at internal/js/modules/k6/grpc/grpc.go:180
common.Throw(rt, err)
}
return s.obj
}
// extractClient extracts & validates a grpc.Client from a sobek.Value.
func extractClient(v sobek.Value, rt *sobek.Runtime) (*Client, error) {
if common.IsNullish(v) {
return nil, errors.New("empty gRPC client")
}
client, ok := v.ToObject(rt).Export().(*Client)
if !ok {
return nil, errors.New("not a gRPC client")
}
if client.conn == nil {
return nil, errors.New("no gRPC connection, you must call connect first")
}
return client, nil
}
View on GitHub (pinned to 93accf6570)
Solutions
- Call `client.connect(address, params)` and let it finish before `new grpc.Stream(...)`
- If the client was closed, create a new Client and connect again
- Ensure connect() is not inside a try/catch that silently continues on failure
Example fix
// before
const client = new grpc.Client();
const stream = new grpc.Stream(client, '/svc/Method');
// after
const client = new grpc.Client();
client.connect('localhost:8080');
const stream = new grpc.Stream(client, '/svc/Method'); Defensive patterns
Strategy: validation
Validate before calling
const client = new grpc.Client(); client.connect(addr); // throws on failure — do not swallow // immediately usable; keep a single owner for the client lifecycle
Try / catch
try {
const stream = new grpc.Stream(client, method);
} catch (e) {
if (String(e.message).includes('must call connect first')) {
client.connect(addr); // or re-create the client
throw e; // next iteration will succeed, or retry here
}
throw e;
} Prevention
- Call connect() immediately after `new grpc.Client()` in the same statement block
- Do not call client.close() mid-iteration if the client is reused by later iterations — close in teardown or at end-of-life only
- Never wrap connect() in a try/catch that continues execution on failure
When it happens
Trigger: Creating `const client = new grpc.Client()` and constructing a Stream without ever calling `client.connect(addr)`; reusing a client after `client.close()` (conn is reset to nil); a connect attempt that failed before the Stream was built.
Common situations: Forgetting connect() when splitting setup across functions; reusing a shared client across iterations after closing it at the end of a previous iteration; connect failure being swallowed earlier in the code.
Related errors
- exported 'setup' must be a function
- exported 'teardown' must be a function
- empty gRPC client
- must be an object with key-value pairs
- no exported functions in script
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/66c956fdd3118971.
Report an issue: GitHub.