{"record":{"id":"77ac95e731c771c6","repo":"grafana/k6","slug":"disposing-element-handles-w","errorCode":null,"errorMessage":"disposing element handles: %w","messagePattern":"disposing element handles: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/js/modules/k6/browser/common/element_handle.go","lineNumber":1285,"sourceCode":"\t\tevalOptions{forceCallable: true, returnByValue: false},\n\t\tjs.QueryAll,\n\t\tparsedSelector,\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"querying all selectors %q: %w\", selector, err)\n\t}\n\tif result == nil {\n\t\t// it is ok to return a nil slice because it means we didn't find any elements.\n\t\treturn nil, nil\n\t}\n\n\thandles, ok := result.(JSHandleAPI)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"getting element handle for selector %q: %w\", selector, ErrJSHandleInvalid)\n\t}\n\tdefer func() {\n\t\tif err := handles.Dispose(); err != nil {\n\t\t\terr = fmt.Errorf(\"disposing element handles: %w\", err)\n\t\t\trerr = errors.Join(err, rerr)\n\t\t}\n\t}()\n\n\tprops, err := handles.GetProperties()\n\tif err != nil {\n\t\t// GetProperties has a rich error already, so we don't need to wrap it.\n\t\treturn nil, err //nolint:wrapcheck\n\t}\n\n\ttype indexedElem struct {\n\t\tindex int\n\t\telem  *ElementHandle\n\t}\n\n\tindexedElems := make([]indexedElem, 0, len(props))\n\tfor key, prop := range props {\n\t\tif el := prop.AsElement(); el != nil {","sourceCodeStart":1267,"sourceCodeEnd":1303,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/element_handle.go#L1267-L1303","documentation":"In queryAll, a deferred Dispose() of the result handle array failed after the main path errored, and the dispose error is joined onto the returned error (element_handle.go:1285). Secondary cleanup noise: dispose fails because the target/context is already destroyed; the primary wrapped error is what to fix.","triggerScenarios":"$$ evaluation returns, the function then errors (or finishes), and the browser page/target closes before the deferred handles.Dispose() runs.","commonSituations":"Iteration teardown: k6 closes the browser while $$ is unwinding; joined with a navigation-race primary error.","solutions":["Address the primary error first; this rides along","Avoid closing the page/browser while $$ results are pending","Safe to ignore when the target is known-closed","Upgrade k6 — close-race handling has improved"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return await el.$$(sel); }\ncatch (e) { /* primary error is actionable; the joined 'disposing element handles' error is teardown noise */ if (isTargetClosed(e)) return []; throw e; }","preventionTips":["Fix the primary wrapped error first","Don't close the browser with $$ pending"],"tags":["browser","cleanup","disposal","race-condition"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}