{"record":{"id":"219e42a3fa31033c","repo":"grafana/k6","slug":"converting-argument-v-w","errorCode":null,"errorMessage":"converting argument '%v': %w","messagePattern":"converting argument '(.+?)': %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/helpers.go","lineNumber":80,"sourceCode":"\t\tcase math.Inf(0):\n\t\t\tunserVal = \"Infinity\"\n\t\tcase math.Inf(-1):\n\t\t\tunserVal = \"-Infinity\"\n\t\tdefault:\n\t\t\tif math.IsNaN(a) {\n\t\t\t\tunserVal = \"NaN\"\n\t\t\t}\n\t\t}\n\n\t\tif unserVal != \"\" {\n\t\t\treturn &cdpruntime.CallArgument{\n\t\t\t\tUnserializableValue: cdpruntime.UnserializableValue(unserVal),\n\t\t\t}, nil\n\t\t}\n\n\t\tb, err := json.Marshal(a)\n\t\tif err != nil {\n\t\t\terr = fmt.Errorf(\"converting argument '%v': %w\", arg, err)\n\t\t}\n\n\t\treturn &cdpruntime.CallArgument{Value: b}, err\n\tcase *ElementHandle:\n\t\treturn convertBaseJSHandleTypes(ctx, execCtx, &a.BaseJSHandle)\n\tcase *BaseJSHandle:\n\t\treturn convertBaseJSHandleTypes(ctx, execCtx, a)\n\tdefault:\n\t\tb, err := json.Marshal(a)\n\t\treturn &cdpruntime.CallArgument{Value: b}, err //nolint:wrapcheck\n\t}\n}\n\nfunc call(\n\tctx context.Context, fn func(context.Context, chan any, chan error), timeout time.Duration,\n) (any, error) {\n\tvar (\n\t\tresult   any","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/helpers.go#L62-L98","documentation":"Before k6 sends arguments of page.evaluate / handle.evaluate / evaluateHandle to the browser, each argument passes through convertArgument: special numbers (NaN, Infinity, -Infinity, -0, int64 above int32) become CDP UnserializableValue, ElementHandle/BaseJSHandle become object references, and remaining numeric values are json.Marshal-ed into a CallArgument. This error wraps a json.Marshal failure at that boundary, so the value cannot cross into the browser. For plain finite float64 values marshal cannot fail, making this a defensive wrap that fires only for exotic, non-JSON-encodable numeric states reaching the branch.","triggerScenarios":"Passing numeric arguments to page.evaluate(fn, arg) or handle.evaluate whose value cannot be JSON-encoded by the runtime; in practice anything that makes encoding/json fail while still hitting the numeric conversion branch of convertArgument in helpers.go:42.","commonSituations":"Passing values from k6/Go-side objects or computed numbers that are not JSON-safe into evaluate calls; edge cases around very large or special numeric values produced by script math; code that assumes any value can be forwarded as an argument.","solutions":["Pass plain JSON-safe primitives (numbers, strings, booleans, plain arrays/objects) as evaluate arguments","Pre-serialize complex values yourself (JSON.stringify) and parse inside the evaluated function","If the value is derived from an object graph with cycles or functions, extract only the needed scalar fields before passing","Use the '%v' rendering of the argument in the message to identify which value failed conversion"],"exampleFix":"// before\nconst big = obj.cyclicGraph;\nawait page.evaluate((v) => use(v), big);\n\n// after\nconst slim = JSON.stringify({ id: obj.id, n: obj.n });\nawait page.evaluate((s) => use(JSON.parse(s)), slim);","handlingStrategy":"validation","validationCode":"function jsonSafe(v) {\n  try { JSON.stringify(v); return v; }\n  catch { return JSON.stringify(v, replacerOrNullSafe); }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass only JSON-serializable primitives and plain objects to evaluate","Pre-stringify complex graphs and parse inside the evaluated function","Never pass functions, symbols, or cyclic structures as arguments"],"tags":["browser","serialization","evaluate","json","arguments"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}