{"record":{"id":"5b7dd38c3d2dfdd7","repo":"grafana/k6","slug":"navigating-s-to-history-entry-d-w","errorCode":null,"errorMessage":"navigating %s 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":1659,"sourceCode":"\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\n\tfor {\n\t\tselect {\n\t\tcase <-p.ctx.Done():\n\t\t\treturn nil, ContextErr(p.ctx)\n\t\tcase <-timeoutCtx.Done():\n\t\t\treturn nil, wrapTimeoutError(ContextErr(timeoutCtx))\n\t\tcase <-ticker.C:\n\t\t\tmainFrame := p.frameManager.MainFrame()\n\t\t\tif mainFrame == nil {\n\t\t\t\tcontinue\n\t\t\t}","sourceCodeStart":1641,"sourceCodeEnd":1677,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/page.go#L1641-L1677","documentation":"GoBackForward polls the page URL after navigating to a history entry (a 50ms ticker) because back/forward-cache restorations do not re-fire lifecycle events. If the wait is aborted — timeout exceeded, page context canceled, or the page's own context done — the error is wrapped here; a DeadlineExceeded is first converted to a k6ext.UserFriendlyError carrying the configured timeout.","triggerScenarios":"page.goBack({timeout: N}) or goForward() where the URL never changes (history entry has the same URL, bfcache restore keeps the URL, or a hash-only change), so the poll runs until the timeout. Also fires when the page closes or the script context is canceled mid-poll.","commonSituations":"Navigating back to a same-URL entry; short timeout option (the default may be too small for slow pages under load); calling goBack() with no history entry change expected; k6 iteration aborting during the wait.","solutions":["Increase the timeout option: page.goBack({ timeout: 30000 })","Verify there is actually a different URL to go back to (check history via the response of goBack, which is null when there is none)","Avoid goBack when the previous entry has the same URL — the URL-change poll cannot distinguish it from failure","Close or abort-check the page before navigating if teardown races it"],"exampleFix":"// before\nconst resp = await page.goBack({ timeout: 1000 }); // too short under load\n\n// after\nconst resp = await page.goBack({ timeout: 30000 });","handlingStrategy":"retry","validationCode":"const historyResp = await page.goBack({ timeout: 30000 });\nif (historyResp === null) console.warn('no history entry to navigate to');","typeGuard":null,"tryCatchPattern":"try {\n  const res = await page.goBack({ timeout: 30000 });\n} catch (e) {\n  if (/navigating (back|forward) to history entry/.test(e.message) && /timed out|timeout/i.test(e.message)) {\n    // URL never changed: same-URL entry or slow page — verify flow instead of retrying blindly\n  } else throw e;\n}","preventionTips":["Pass an explicit generous timeout under load","Do not use goBack to 'reload' a same-URL history entry — the URL poll cannot detect success","Confirm the back entry actually differs in URL before waiting on it"],"tags":["browser","navigation","history","timeout","bfcache"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}