{"record":{"id":"05fe180de489d54b","repo":"grafana/k6","slug":"unmarshaling-polling-type-w","errorCode":null,"errorMessage":"unmarshaling polling type: %w","messagePattern":"unmarshaling polling type: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/frame_options.go","lineNumber":181,"sourceCode":"\t\"raf\":      PollingRaf,\n\t\"mutation\": PollingMutation,\n\t\"interval\": PollingInterval,\n}\n\n// MarshalJSON marshals the enum as a quoted JSON string.\nfunc (p PollingType) MarshalJSON() ([]byte, error) {\n\tbuffer := bytes.NewBufferString(`\"`)\n\tbuffer.WriteString(pollingTypeToString[p])\n\tbuffer.WriteString(`\"`)\n\treturn buffer.Bytes(), nil\n}\n\n// UnmarshalJSON unmarshals a quoted JSON string to the enum value.\nfunc (p *PollingType) UnmarshalJSON(b []byte) error {\n\tvar j string\n\terr := json.Unmarshal(b, &j)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unmarshaling polling type: %w\", err)\n\t}\n\t// Note that if the string cannot be found then it will be set to the zero value.\n\t*p = pollingTypeToID[j]\n\treturn nil\n}\n\ntype FrameWaitForFunctionOptions struct {\n\tPolling  PollingType   `json:\"polling\"`\n\tInterval int64         `json:\"interval\"`\n\tTimeout  time.Duration `json:\"timeout\"`\n}\n\ntype FrameWaitForLoadStateOptions struct {\n\tTimeout time.Duration `json:\"timeout\"`\n}\n\ntype FrameWaitForNavigationOptions struct {\n\tURL       string         `json:\"url\"`","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/frame_options.go#L163-L199","documentation":"PollingType.UnmarshalJSON (frame_options.go:181) decodes the `polling` field of FrameWaitForFunctionOptions from JSON and only accepts a quoted JSON string. If the payload contains a non-string (bare number, boolean, object), json.Unmarshal fails and the error is wrapped with this message. The accepted strings map through pollingTypeToID: \"raf\", \"mutation\", \"interval\"; unknown strings silently become the zero value instead of erroring.","triggerScenarios":"Decoding option JSON into FrameWaitForFunctionOptions where polling is serialized as {\"polling\": 100} or {\"polling\": {\"interval\": 100}} rather than {\"polling\": \"raf\"}. Note the JavaScript API path (FrameWaitForFunctionOptions.Parse) handles numeric polling separately; this error only fires on the JSON unmarshal path.","commonSituations":"Tooling or tests that serialize/deserialize k6 browser options, or Go code that feeds program-generated JSON into the browser module's option structs with a numeric polling value.","solutions":["Encode polling as one of the quoted strings \"raf\", \"mutation\" or \"interval\" when producing JSON for this struct","If you need a custom polling interval, pass it as a JS number through the scripting API (waitForFunction options) rather than through JSON","If you produce the JSON from Go, marshal with PollingType.MarshalJSON so it stays a quoted string"],"exampleFix":"// before (invalid JSON for the enum)\n\"options\": { \"polling\": 100, \"timeout\": 30000 }\n\n// after\n\"options\": { \"polling\": \"raf\", \"timeout\": 30000 }\n// custom interval via JS API instead:\nframe.waitForFunction(() => !!window.done, {}, { polling: 100 })","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isPollingJson(v: unknown): v is string {\n  return typeof v === 'string' && ['raf', 'mutation', 'interval'].includes(v);\n}\n// before serializing: if (!isPollingJson(opts.polling) && typeof opts.polling !== 'number') throw new Error('invalid polling');","tryCatchPattern":null,"preventionTips":["Keep numeric polling intervals in the JS API layer, not in serialized option JSON","Round-trip test your option JSON through the same marshal/unmarshal code paths k6 uses"],"tags":["browser","json","enum","waitforfunction","polling"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}