{"record":{"id":"4a3fbf8c8bc37ffb","repo":"grafana/k6","slug":"converting-argument-q-in-execution-context-id-d","errorCode":null,"errorMessage":"converting argument %q in execution context ID %d and frame ID %v: %w","messagePattern":"converting argument %q in execution context ID (.+?) and frame ID (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/execution_context.go","lineNumber":191,"sourceCode":"\t\tDo(context.Context) (*runtime.RemoteObject, *runtime.ExceptionDetails, error)\n\t}\n\n\tif !opts.forceCallable {\n\t\tif !hasSourceURL(js) {\n\t\t\tjs += \"\\n\" + suffix\n\t\t}\n\n\t\taction = runtime.Evaluate(js).\n\t\t\tWithContextID(e.id).\n\t\t\tWithReturnByValue(opts.returnByValue).\n\t\t\tWithAwaitPromise(true).\n\t\t\tWithUserGesture(true)\n\t} else {\n\t\tvar arguments []*runtime.CallArgument\n\t\tfor _, arg := range args {\n\t\t\tresult, err := convertArgument(apiCtx, e, arg)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"converting argument %q \"+\n\t\t\t\t\t\"in execution context ID %d and frame ID %v: %w\",\n\t\t\t\t\targ, e.id, e.Frame().ID(), err)\n\t\t\t}\n\t\t\targuments = append(arguments, result)\n\t\t}\n\n\t\tjs += \"\\n\" + suffix + \"\\n\"\n\t\taction = runtime.CallFunctionOn(js).\n\t\t\tWithArguments(arguments).\n\t\t\tWithExecutionContextID(e.id).\n\t\t\tWithReturnByValue(opts.returnByValue).\n\t\t\tWithAwaitPromise(true).\n\t\t\tWithUserGesture(true)\n\t}\n\n\tvar (\n\t\tremoteObject     *runtime.RemoteObject\n\t\texceptionDetails *runtime.ExceptionDetails","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/execution_context.go#L173-L209","documentation":"While evaluating a script with arguments (page.evaluate / evaluateHandle style calls), k6 converts every argument into a CDP CallArgument via convertArgument (helpers.go:42). Supported values: int64, float64 (with NaN/Infinity/-0 special cases), ElementHandle/BaseJSHandle, and anything json.Marshal can serialize. Values that fail JSON marshaling — functions, cyclic structures, unsupported types — or a leaked sobek.Value ('sobek.Value escaped') produce this error naming the offending argument.","triggerScenarios":"Passing a function as an argument instead of it being the evaluated function: page.evaluate((cb) => cb(2), (n) => n * 2); objects with circular references; passing a JSHandle created in a different or already-closed page; any value that cannot be JSON-serialized.","commonSituations":"Confusing which function is 'the script' versus 'an argument' in evaluate(fn, ...args); sending page-internal objects or k6 module objects as arguments; passing deeply nested or cyclic structures built during the test; handles from a closed page.","solutions":["Pass only serializable values (strings, numbers, booleans, plain arrays/objects) as arguments","To pass a DOM node, obtain an ElementHandle and pass the handle itself","Strip cycles / project out only needed fields before passing large objects","Double-check argument order: evaluate(fn, ...args)"],"exampleFix":"// before\nconst r = await page.evaluate((cb) => cb(2), (n) => n * 2); // function passed as argument\n\n// after\nconst r = await page.evaluate((n) => n * 2, 2);","handlingStrategy":"validation","validationCode":"function serializable(v) {\n  if (v === null) return true;\n  const t = typeof v;\n  if (t === 'function' || t === 'symbol' || t === 'bigint') return false;\n  if (t !== 'object') return true;\n  if (Array.isArray(v)) return v.every(serializable);\n  return Object.values(v).every(serializable);\n}\nconst args = [1, 'a', { x: 1 }];\nif (!args.every(serializable)) throw new Error('non-serializable evaluate argument');\nawait page.evaluate(fn, ...args);","typeGuard":"function isPlainArg(v) {\n  if (v && typeof v === 'object' && typeof v.click === 'function') return true; // ElementHandle\n  return v === null || ['string', 'number', 'boolean', 'undefined'].includes(typeof v);\n}","tryCatchPattern":"try {\n  await page.evaluate(fn, arg);\n} catch (e) {\n  if (/converting argument/.test(e.message)) {\n    // strip functions/cycles from args, or pass an ElementHandle, then retry\n  } else throw e;\n}","preventionTips":["evaluate(fn, ...args): only the first parameter is code","JSON-round-trip objects (JSON.parse(JSON.stringify(x))) to kill cycles","Pass handles for DOM things, plain data for everything else","Never pass a k6 module or page object as an argument"],"tags":["browser","evaluate","serialization","type-mismatch"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}