{"record":{"id":"f04f5fc5343a45ab","repo":"grafana/k6","slug":"invalid-tls-value-v-expected-optional-keys","errorCode":null,"errorMessage":"invalid tls value: '%#v', expected (optional) keys: cert, key, password, and cacerts","messagePattern":"invalid tls value: '%#v', expected \\(optional\\) keys: cert, key, password, and cacerts","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/grpc/params.go","lineNumber":225,"sourceCode":"\t\t\tvar ok bool\n\t\t\tresult.Authority, ok = v.(string)\n\t\t\tif !ok {\n\t\t\t\treturn result, fmt.Errorf(\"invalid authority value: '%#v', it needs to be a string\", v)\n\t\t\t}\n\t\tdefault:\n\t\t\treturn result, fmt.Errorf(\"unknown connect param: %q\", k)\n\t\t}\n\t}\n\n\treturn result, nil\n}\n\nfunc parseConnectTLSParam(params *connectParams, v any) error {\n\tvar ok bool\n\tparams.TLS, ok = v.(map[string]any)\n\n\tif !ok {\n\t\treturn fmt.Errorf(\"invalid tls value: '%#v', expected (optional) keys: cert, key, password, and cacerts\", v)\n\t}\n\t// optional map keys below\n\tif cert, certok := params.TLS[\"cert\"]; certok {\n\t\tif _, ok = cert.(string); !ok {\n\t\t\treturn fmt.Errorf(\"invalid tls cert value: '%#v', it needs to be a PEM formatted string\", v)\n\t\t}\n\t}\n\tif key, keyok := params.TLS[\"key\"]; keyok {\n\t\tif _, ok = key.(string); !ok {\n\t\t\treturn fmt.Errorf(\"invalid tls key value: '%#v', it needs to be a PEM formatted string\", v)\n\t\t}\n\t}\n\tif pass, passok := params.TLS[\"password\"]; passok {\n\t\tif _, ok = pass.(string); !ok {\n\t\t\treturn fmt.Errorf(\"invalid tls password value: '%#v', it needs to be a string\", v)\n\t\t}\n\t}\n\tif cacerts, cacertsok := params.TLS[\"cacerts\"]; cacertsok {","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/grpc/params.go#L207-L243","documentation":"Thrown by k6's gRPC Client.connect() when the tls connect option is not an object. parseConnectTLSParam (internal/js/modules/k6/grpc/params.go:220-226) requires the value of the 'tls' key to be a map (JS object) whose optional keys are cert, key, password, cacerts; anything else — a string, boolean, number, or array — fails the type assertion v.(map[string]any) and produces this error.","triggerScenarios":"Passing tls: true (a common mistake from older k6 versions where tls was a boolean), tls: 'cert.pem', tls: [cert], or tls: null exported to a non-object. Note the message prints the whole offending value with %#v, so you see exactly what was received.","commonSituations":"Scripts written for k6 <0.42-style APIs where TLS was toggled differently; passing a file path string instead of the file contents object; double-wrapping the tls object ({ tls: { tls: {...} } }).","solutions":["Make the tls option an object literal: tls: { ... } with only the keys cert, key, password, cacerts.","If you only want the system CAs, pass tls: {} (empty object) or omit the tls option entirely.","To disable TLS, use plaintext: true instead of tls: false.","Check the printed %#v value in the message to see what type was actually passed."],"exampleFix":"// before\nclient.connect('host:443', { tls: true });\n\n// after\nclient.connect('host:443', { plaintext: false, tls: {} });","handlingStrategy":"validation","validationCode":"function validateTlsParam(params = {}) {\n  if (!('tls' in params)) return;\n  if (typeof params.tls !== 'object' || params.tls === null || Array.isArray(params.tls)) {\n    throw new Error('connect param tls must be an object with optional keys cert, key, password, cacerts');\n  }\n}","typeGuard":"const isTlsObject = (v) => v === undefined || (typeof v === 'object' && v !== null && !Array.isArray(v));","tryCatchPattern":"try { client.connect(addr, { tls }); } catch (e) { if (/invalid tls value/.test(e.message)) { /* fall back to default TLS: client.connect(addr, {}) */ } throw e; }","preventionTips":["Remember tls takes no boolean — plaintext: true is the way to disable TLS.","Centralize TLS config in one helper so the object shape is checked once."],"tags":["grpc","tls","validation","connect"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}