grafana/k6 · error
unable to serialise request object: %w
Error message
unable to serialise request object: %w
What it means
After normalization, the request object is marshaled with MarshalJSON; values JSON cannot represent (functions, Symbols, BigInts) or a throwing toJSON getter make marshaling fail, wrapped as 'unable to serialise request object' (internal/js/modules/k6/grpc/client.go:393). Unlike the normalize step, this is about value types, not reference cycles.
Source
Thrown at internal/js/modules/k6/grpc/client.go:393
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)
}
b, err := normalized.ToObject(c.vu.Runtime()).MarshalJSON()
if err != nil {
return grpcReq, fmt.Errorf("unable to serialise request object: %w", err)
}
p.SetSystemTags(state, c.addr, method)
return grpcext.InvokeRequest{
Method: method,
MethodDescriptor: methodDesc,
Timeout: p.Timeout,
DiscardResponseMessage: p.DiscardResponseMessage,
Message: b,
TagsAndMeta: &p.TagsAndMeta,
Metadata: p.Metadata,
}, nil
}
// normalizeNumberStrings recursively traverses a sobek.Value. It creates a deep copy of any
// objects or arrays, and converts special float values (NaN, Infinity) to their
// string representations for proper JSON serialization.View on GitHub (pinned to 93accf6570)
Solutions
- Convert BigInts to Number or String before invoking
- Strip functions and non-data fields; pass a plain data object built specifically for the message
- Pre-serialize once with JSON.stringify(req) in the script to get a precise early error with a stack trace
Example fix
// before
client.invoke('/svc/Set', { userId: 9007199254740993n });
// after
client.invoke('/svc/Set', { userId: '9007199254740993' }); // string keeps precision Defensive patterns
Strategy: validation
Validate before calling
// fails on BigInt/functions with a precise JS stack trace before invoke()
function assertSerializable(req) {
try { JSON.stringify(req); }
catch (e) { throw new Error(`request not JSON-serializable: ${e.message}`); }
return req;
}
client.invoke(method, assertSerializable(req)); Type guard
function isJsonSafe(v) {
if (typeof v === 'bigint' || typeof v === 'function' || typeof v === 'symbol') return false;
if (v === null || typeof v !== 'object') return true;
return Object.values(v).every(isJsonSafe);
} Try / catch
try { client.invoke(m, req); } catch (e) { if (/unable to serialise request object/.test(e.message)) { /* convert BigInts, strip functions, retry */ } throw e; } Prevention
- Convert BigInt IDs to strings or Numbers before invoke
- Pass plain data objects, not objects carrying methods or SDK handles
- Pre-check with JSON.stringify in dev builds of the script
When it happens
Trigger: client.invoke(m, { id: 10n }) with a BigInt; passing a function or Symbol as a field; objects whose custom toJSON/getter throws during serialization.
Common situations: IDs computed as BigInt to avoid precision loss; accidentally including a function, logger, or SDK client in the payload; subclassed objects with exotic accessors.
Related errors
- couldn't unmarshal protoset file %s: %w
- unable to normalize number strings: %w
- cyclic reference to an object found
- gRPC exporter endpoint is required
- invalid metric type
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/045175513824231b.
Report an issue: GitHub.