{"record":{"id":"602fdbee886680f3","repo":"grafana/k6","slug":"the-argument-to-map-must-be-a-function","errorCode":null,"errorMessage":"the argument to map() must be a function","messagePattern":"the argument to map\\(\\) must be a function","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"js/modules/k6/html/html.go","lineNumber":421,"sourceCode":"\n\tcase Selection:\n\t\treturn s.sel.IsSelection(val.sel)\n\n\tdefault:\n\t\tsobekFn, isFn := sobek.AssertFunction(v)\n\t\tif !isFn {\n\t\t\tcommon.Throw(s.rt, errors.New(\"the argument to is() must be a function, a selector or a selection\"))\n\t\t}\n\n\t\treturn s.sel.IsFunction(s.buildMatcher(v, sobekFn))\n\t}\n}\n\n// Map implements ES5 Array.prototype.map\nfunc (s Selection) Map(v sobek.Value) []sobek.Value {\n\tsobekFn, isFn := sobek.AssertFunction(v)\n\tif !isFn {\n\t\tcommon.Throw(s.rt, errors.New(\"the argument to map() must be a function\"))\n\t}\n\n\tvar values []sobek.Value\n\ts.sel.Each(func(idx int, sel *goquery.Selection) {\n\t\tselection := &Selection{sel: sel, URL: s.URL, rt: s.rt}\n\n\t\tif fnRes, fnErr := sobekFn(v, s.rt.ToValue(idx), s.rt.ToValue(selection)); fnErr == nil {\n\t\t\tvalues = append(values, fnRes)\n\t\t}\n\t})\n\n\treturn values\n}\n\nfunc (s Selection) Slice(start int, def ...int) Selection {\n\t// We are forced to check that def[0] is inferior to the length of the array\n\t// otherwise the s.sel.Slice panics. Besides returning the whole array when\n\t// the end value for slicing is superior to the array length is standard in js.","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/js/modules/k6/html/html.go#L403-L439","documentation":"Selection.Map() in k6's HTML module implements ES5 Array.prototype.map over the matched elements and requires a single function argument; sobek.AssertFunction rejects everything else. Results of the callback are collected into a plain array of sobek values (callbacks that throw are silently skipped, their result omitted).","triggerScenarios":"Calling map() with a selector string, no argument, or a non-callable value; expecting jQuery-style arguments without providing the callback.","commonSituations":"Attempting sel.map('div') to project elements (should be find + map); refactor that dropped the lambda; passing an arrow function stored in a variable that is actually undefined.","solutions":["Pass a callback: sel.map((idx, el) => el.text())","For selecting subsets first, chain .find() or .filter() before .map()","Confirm the callback variable is defined at call time (typos yield undefined)"],"exampleFix":"// before\nconst texts = selection.map('div');\n\n// after\nconst texts = selection.find('div').map((idx, el) => el.text());","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"if (typeof fn !== 'function') throw new TypeError('map() expects a function');\nconst values = sel.map(fn);","tryCatchPattern":null,"preventionTips":["Always pass (idx, el) => ... to map()","Verify callback variables are assigned (typos give undefined)","Project data in the callback; do not pass selectors to map()"],"tags":["javascript","html","dom","iteration","k6-html"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}