{"record":{"id":"80dd296d830a5957","repo":"grafana/k6","slug":"invalid-type-t-expected-string-byte-or-arrayb","errorCode":null,"errorMessage":"invalid type %T, expected string, []byte or ArrayBuffer","messagePattern":"invalid type %T, expected string, \\[\\]byte or ArrayBuffer","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/webcrypto/types.go","lineNumber":35,"sourceCode":"// byteLength is a type alias for the length of a byte slice.\ntype byteLength int\n\n// asBitLength returns the length of the byte slice in bits.\nfunc (b byteLength) asBitLength() bitLength {\n\treturn bitLength(b) * 8\n}\n\n// ToBytes tries to return a byte slice from compatible types.\nfunc ToBytes(data any) ([]byte, error) {\n\tswitch dt := data.(type) {\n\tcase []byte:\n\t\treturn dt, nil\n\tcase string:\n\t\treturn []byte(dt), nil\n\tcase sobek.ArrayBuffer:\n\t\treturn dt.Bytes(), nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid type %T, expected string, []byte or ArrayBuffer\", data)\n\t}\n}\n","sourceCodeStart":17,"sourceCodeEnd":38,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/webcrypto/types.go#L17-L38","documentation":"webcrypto's ToBytes helper coerces raw key material and payload arguments. k6 only accepts strings, Go []byte values, and sobek.ArrayBuffer objects; anything else (number, null, plain object, DataView, BigInt, function) reaches the default branch and raises this TypeError-style error naming the offending Go type.","triggerScenarios":"Passing a non-buffer first argument to crypto.subtle.encrypt/decrypt/sign/verify/deriveBits/deriveKey or importKey('raw'|'jwk', ...), e.g. importKey('raw', 42, ...), encrypt(alg, key, {data:...}), or a DataView/JSON object instead of a string/ArrayBuffer. Note DataView is NOT in the accepted list even though ArrayBuffer is.","commonSituations":"Passing a parsed JSON object where the code meant obj.password (a string); passing a DataView created from a buffer; passing null after a failed upstream fetch/parse; assuming numbers are coerced to strings like in console.log; passing a TypedArray of a wide element type whose export is not []byte.","solutions":["Convert the value to a string or ArrayBuffer before the call: String(x), x.toString(), or buffer.slice(0) for ArrayBuffers","Replace DataView inputs with their underlying ArrayBuffer: dv.buffer","For JSON data, JSON.stringify the object instead of passing it directly","If the value may legitimately be absent, guard with a default: data ?? ''"],"exampleFix":"// before\nconst ct = await crypto.subtle.encrypt(alg, key, jsonDataObj); // object -> invalid type map[string]interface {}\n\n// after\nconst ct = await crypto.subtle.encrypt(alg, key, JSON.stringify(jsonDataObj));\n// or: new TextEncoder().encode(JSON.stringify(jsonDataObj)) for explicit bytes","handlingStrategy":"type-guard","validationCode":"function toCryptoBytes(v) {\n  if (typeof v === 'string') return v;\n  if (v instanceof ArrayBuffer) return v;\n  if (ArrayBuffer.isView(v)) return v.buffer; // DataView/TypedArray -> its ArrayBuffer\n  throw new Error(`unsupported crypto input: ${typeof v}`);\n}\nawait crypto.subtle.encrypt(alg, key, toCryptoBytes(data));","typeGuard":"const isCryptoBytes = v => typeof v === 'string' || v instanceof ArrayBuffer;\n// TypedArrays whose export is []byte are fine too; DataView must be converted:\nconst okInput = v => typeof v === 'string' || v instanceof ArrayBuffer || (ArrayBuffer.isView(v) && v.constructor.name === 'Uint8Array');","tryCatchPattern":"try { await crypto.subtle.encrypt(alg, key, data); }\ncatch (e) { if (/invalid type/.test(e.message)) throw new TypeError(`encrypt payload must be string/ArrayBuffer, got ${typeof data}`); throw e; }","preventionTips":["Establish one boundary helper (toBytes) at the top of the script and route all crypto inputs through it","Prefer TextEncoder().encode() for strings when you want explicit bytes","JSON.stringify objects before hashing/encrypting; never pass parsed JSON directly","Null-check data coming from network/parse steps before it reaches crypto APIs"],"tags":["webcrypto","type-error","input-validation","sobek"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}