{"record":{"id":"521842f96b0f9e77","repo":"grafana/k6","slug":"sharedarray-is-immutable","errorCode":null,"errorMessage":"SharedArray is immutable","messagePattern":"SharedArray is immutable","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/data/share.go","lineNumber":37,"sourceCode":"\tisFrozen sobek.Callable\n\tparse    sobek.Callable\n}\n\nfunc (s sharedArray) wrap(rt *sobek.Runtime) sobek.Value {\n\tfreeze, _ := sobek.AssertFunction(rt.GlobalObject().Get(\"Object\").ToObject(rt).Get(\"freeze\"))\n\tisFrozen, _ := sobek.AssertFunction(rt.GlobalObject().Get(\"Object\").ToObject(rt).Get(\"isFrozen\"))\n\tparse, _ := sobek.AssertFunction(rt.GlobalObject().Get(\"JSON\").ToObject(rt).Get(\"parse\"))\n\treturn rt.NewDynamicArray(wrappedSharedArray{\n\t\tsharedArray: s,\n\t\trt:          rt,\n\t\tfreeze:      freeze,\n\t\tisFrozen:    isFrozen,\n\t\tparse:       parse,\n\t})\n}\n\nfunc (s wrappedSharedArray) Set(_ int, _ sobek.Value) bool {\n\tpanic(s.rt.NewTypeError(\"SharedArray is immutable\")) // this is specifically a type error\n}\n\nfunc (s wrappedSharedArray) SetLen(_ int) bool {\n\tpanic(s.rt.NewTypeError(\"SharedArray is immutable\")) // this is specifically a type error\n}\n\nfunc (s wrappedSharedArray) Get(index int) sobek.Value {\n\tif index < 0 || index >= len(s.arr) {\n\t\treturn sobek.Undefined()\n\t}\n\tval, err := s.parse(sobek.Undefined(), s.rt.ToValue(s.arr[index]))\n\tif err != nil {\n\t\tcommon.Throw(s.rt, err)\n\t}\n\n\terr = s.deepFreeze(s.rt, val)\n\tif err != nil {\n\t\tcommon.Throw(s.rt, err)","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/data/share.go#L19-L55","documentation":"SharedArray wraps a memory-shared, once-initialized array behind a frozen dynamic array so every VU sees the same data without per-VU copies. The Set trap intentionally raises a TypeError on any element assignment (arr[i] = v) — immutability is the contract that makes sharing safe, so writes are rejected, not ignored.","triggerScenarios":"const data = new SharedArray('data', () => [...]); then data[0] = 'x', data[i] = obj inside a VU function, or any indexed write (including via destructuring-style helpers that assign back). Only reads and JSON.parse-on-read (Get) are implemented; there is no code path that permits element mutation.","commonSituations":"Marking test data as 'used' (data[i].seen = true or data[i] = null) — impossible by design; sharing arrays between iterations and trying to update state per iteration; porting plain-array test data to SharedArray for memory savings and forgetting to remove in-place shuffles/marks; helper libraries (shuffle, uniq) that sort/assign in place.","solutions":["Mutate a per-VU copy instead: const local = Array.from(data) (or data.map(x => JSON.parse(JSON.stringify(x)))) then modify local","Track per-iteration state in a separate plain array or a vu-level variable, keyed by index","If you need write-once-then-share semantics, build the final data inside the SharedArray initializer function itself","Use in-place-safe helpers: copy before sort/shuffle (const sorted = [...local].sort())"],"exampleFix":"// before\nconst users = new SharedArray('users', () => loadUsers());\nexport default function () { users[0] = 'taken'; } // TypeError: SharedArray is immutable\n\n// after\nconst users = new SharedArray('users', () => loadUsers());\nexport default function () {\n  const taken = Array.from(users); // private per-VU copy\n  taken[0] = 'taken';\n}","handlingStrategy":"fallback","validationCode":"// treat SharedArray as read-only; copy before any mutation\nconst writable = (shared) => Array.from(shared);\nconst local = writable(data);\nlocal[0] = 'taken'; // safe","typeGuard":"// k6 >= 0.5x: SharedArray instances can be detected by tag\nconst isShared = a => a && Object.prototype.toString.call(a) === '[object SharedArray]'; // if exposed; otherwise track via instanceof/constructor at creation site","tryCatchPattern":null,"preventionTips":["Convention: name SharedArray fixtures READONLY_* or keep them in a separate file imported as const","Do all sorting/shuffling/marking on Array.from(shared) copies inside the VU function","Keep per-iteration state outside the SharedArray (cursor vars, plain arrays)","Review third-party helpers (shuffle, uniq) for in-place mutation before feeding them shared data"],"tags":["shared-array","immutability","type-error","data","memory"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}