{"record":{"id":"bd266b0e516cb2c3","repo":"grafana/k6","slug":"navigating-to-history-entry-d-w","errorCode":null,"errorMessage":"navigating to history entry %d: %w","messagePattern":"navigating to history entry (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/page.go","lineNumber":1648,"sourceCode":"\t\treturn nil, err\n\t}\n\n\ttargetIndex := currentIndex + int64(delta)\n\n\t// Check boundaries\n\tif targetIndex < 0 || targetIndex >= int64(len(entries)) {\n\t\treturn nil, nil //nolint:nilnil\n\t}\n\n\thistoryEntryID := entries[targetIndex].ID\n\ttargetURL := entries[targetIndex].URL\n\n\ttimeoutCtx, timeoutCancelFn := context.WithTimeout(p.ctx, opts.Timeout)\n\tdefer timeoutCancelFn()\n\n\tnavAction := page.NavigateToHistoryEntry(historyEntryID)\n\tif err := navAction.Do(cdp.WithExecutor(p.ctx, p.session)); err != nil {\n\t\treturn nil, fmt.Errorf(\"navigating to history entry %d: %w\", historyEntryID, err)\n\t}\n\n\twrapTimeoutError := func(err error) error {\n\t\tif errors.Is(err, context.DeadlineExceeded) {\n\t\t\terr = &k6ext.UserFriendlyError{\n\t\t\t\tErr:     err,\n\t\t\t\tTimeout: opts.Timeout,\n\t\t\t}\n\t\t}\n\t\tp.logger.Debugf(\"Page:GoBackForward\", \"timeoutCtx done: %v\", err)\n\t\treturn fmt.Errorf(\"navigating %s to history entry %d: %w\", direction, historyEntryID, err)\n\t}\n\n\t// Poll for URL change, don't rely on lifecycle events since bfcache\n\t// restorations don't re-fire them.\n\tticker := time.NewTicker(50 * time.Millisecond)\n\tdefer ticker.Stop()\n","sourceCodeStart":1630,"sourceCodeEnd":1666,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/page.go#L1630-L1666","documentation":"In Page's GoBackForward helper, after resolving the target history entry from page.getNavigationHistory, the CDP command Page.navigateToHistoryEntry is executed. This error wraps a failure of that command itself — the history entry exists but navigating to it failed at the protocol level.","triggerScenarios":"page.goBack()/go.forward() when the renderer refuses the navigation (crashed target, session detached), or the history entry became invalid between listing and navigating (rapid consecutive navigations).","commonSituations":"Calling goBack() twice in quick succession; going back right as the page closes; renderer under memory pressure rejecting the command.","solutions":["Space out back/forward calls (await each navigation fully)","Check that the previous goBack/goForward returned a non-null response before issuing another","Verify the page is not closing before navigating history","Retry the navigation once if it failed transiently"],"exampleFix":"// before\nawait page.goBack();\nawait page.goBack(); // second call before first settles\n\n// after\nconst res = await page.goBack();\nif (res) await page.goBack();","handlingStrategy":"try-catch","validationCode":"if (page.isClosed()) throw new Error('page closed before history navigation');","typeGuard":null,"tryCatchPattern":"try {\n  const res = await page.goBack();\n  if (res === null) return; // no history entry\n} catch (e) {\n  if (!/navigating to history entry/.test(e.message)) throw e;\n}","preventionTips":["Fully await each goBack/goForward before issuing the next","Treat a null response as 'no history' and stop navigating"],"tags":["browser","navigation","history","cdp"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}