{"record":{"id":"ba4df91c57d5d0b0","repo":"grafana/k6","slug":"only-arrays-can-be-made-into-sharedarray","errorCode":null,"errorMessage":"only arrays can be made into SharedArray","messagePattern":"only arrays can be made into SharedArray","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/data/data.go","lineNumber":206,"sourceCode":"\t\treturn arr, nil\n\t}\n\n\tarr, err := builder()\n\tif err != nil {\n\t\treturn arr, err\n\t}\n\ts.data[name] = arr\n\treturn arr, nil\n}\n\nfunc getSharedArrayFromCall(rt *sobek.Runtime, call sobek.Callable) (sharedArray, error) {\n\tsobekValue, err := call(sobek.Undefined())\n\tif err != nil {\n\t\treturn sharedArray{}, err\n\t}\n\tobj := sobekValue.ToObject(rt)\n\tif obj.ClassName() != \"Array\" {\n\t\treturn sharedArray{}, errors.New(\"only arrays can be made into SharedArray\") // TODO better error\n\t}\n\tarr := make([]string, obj.Get(\"length\").ToInteger())\n\n\tstringifyFunc, _ := sobek.AssertFunction(rt.GlobalObject().Get(\"JSON\").ToObject(rt).Get(\"stringify\"))\n\tvar val sobek.Value\n\tfor i := range arr {\n\t\tval, err = stringifyFunc(sobek.Undefined(), obj.Get(strconv.Itoa(i)))\n\t\tif err != nil {\n\t\t\treturn sharedArray{}, err\n\t\t}\n\t\tarr[i] = val.String()\n\t}\n\n\treturn sharedArray{arr: arr}, nil\n}\n","sourceCodeStart":188,"sourceCodeEnd":222,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/js/modules/k6/data/data.go#L188-L222","documentation":"k6 calls your SharedArray builder once and inspects the returned value's JS class via obj.ClassName(). SharedArray only supports plain JavaScript arrays because each element gets JSON.stringify-ed into a packed Go slice that VUs mmap-style share; an object, Map, typed array, string or undefined therefore fails with this error (the source even carries a 'TODO better error').","triggerScenarios":"A builder returning an object (e.g. returning JSON.parse of an object document), a Map/Set, a string, or implicitly undefined (missing return statement). The check happens after the builder has run, so side effects inside the builder have already executed.","commonSituations":"Data file is a JSON object ({\"users\": [...]}) rather than an array - the natural builder returns the whole object; forgetting the return keyword in the builder; returning a generator or iterator result.","solutions":["Make the builder return a plain array literal: if the JSON is an object, return JSON.parse(open('./data.json')).users.","Add (or fix) the return statement in the builder function.","Flatten nested structures into an array of records before returning; per-item fields are fine, the top-level value must be an Array."],"exampleFix":"// before: data.json is { \"users\": [ ... ] }\nnew SharedArray('users', () => JSON.parse(open('./data.json'))); // throws: only arrays\n\n// after\nnew SharedArray('users', () => JSON.parse(open('./data.json')).users);","handlingStrategy":"validation","validationCode":"// dry-run the builder once at init to fail fast with a clear message\nconst build = () => JSON.parse(open('./data.json')).items; // may be an object\nconst probe = build();\nif (!Array.isArray(probe)) {\n  throw new Error(`SharedArray builder must return an array, got ${Object.prototype.toString.call(probe)}`);\n}\nconst arr = new SharedArray('data', build);","typeGuard":"const returnsArray = (fn) => Array.isArray(fn());","tryCatchPattern":null,"preventionTips":["Normalize data files to top-level JSON arrays.","Dry-run builders at init so bad shapes fail before the test starts."],"tags":["k6","sharedarray","validation","return-type"],"backgroundTag":"invalid-return-type","analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":"2026-08-18T03:05:52.393Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}