{"record":{"id":"afe777cecf3a161e","repo":"microsoft/playwright","slug":"navigation-to-url-is-interrupted-by-another-n","errorCode":null,"errorMessage":"Navigation to \"${url}\" is interrupted by another navigation to \"${event.url}\"","messagePattern":"Navigation to \"(.+?)\" is interrupted by another navigation to \"(.+?)\"","errorType":"exception","errorClass":"NavigationAbortedError","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/frames.ts","lineNumber":734,"sourceCode":"      this.off(Frame.Events.InternalNavigation, collectNavigations);\n    }\n\n    let event: NavigationEvent;\n    if (navigateResult.newDocumentId) {\n      const predicate = (event: NavigationEvent) => {\n        // We are interested either in this specific document, or any other document that\n        // did commit and replaced the expected document.\n        return event.newDocument && (event.newDocument.documentId === navigateResult.newDocumentId || !event.error);\n      };\n      const events = navigationEvents.filter(predicate);\n      if (events.length)\n        event = events[0];\n      else\n        event = await helper.waitForEvent(progress, this, Frame.Events.InternalNavigation, predicate).promise;\n      if (event.newDocument!.documentId !== navigateResult.newDocumentId) {\n        // This is just a sanity check. In practice, new navigation should\n        // cancel the previous one and report \"request cancelled\"-like error.\n        throw new NavigationAbortedError(navigateResult.newDocumentId, `Navigation to \"${url}\" is interrupted by another navigation to \"${event.url}\"`);\n      }\n      if (event.error)\n        throw event.error;\n    } else {\n      // Wait for same document navigation.\n      const predicate = (e: NavigationEvent) => !e.newDocument;\n      const events = navigationEvents.filter(predicate);\n      if (events.length)\n        event = events[0];\n      else\n        event = await helper.waitForEvent(progress, this, Frame.Events.InternalNavigation, predicate).promise;\n    }\n\n    if (!this._firedLifecycleEvents.has(waitUntil))\n      await helper.waitForEvent(progress, this, Frame.Events.AddLifecycle, (e: types.LifecycleEvent) => e === waitUntil).promise;\n\n    const request = event.newDocument ? event.newDocument.request : undefined;\n    const response = request ? await request._finalRequest().response(progress) : null;","sourceCodeStart":716,"sourceCodeEnd":752,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/frames.ts#L716-L752","documentation":"During goto, Playwright waits for the navigated document to commit. If a different document commits first (a second navigation supersedes the one goto started), it throws NavigationAbortedError explaining that the navigation to url was interrupted by a navigation to a different url.","triggerScenarios":"page.goto(url) where, before the expected document commits, the page triggers another navigation: client-side redirects, meta-refresh, JS location changes, history APIs, or a concurrent click causing navigation.","commonSituations":"SPAs that redirect after load; login flows that bounce through auth then home; a click handler firing during goto; pre-existing timers/redirects racing the navigation; flaky tests under slow network.","solutions":["await the final destination: use page.waitForURL(finalUrl) chained with the action that triggers the redirect instead of a single goto.","Remove or stabilize the competing navigation source (disable the meta-refresh, gate the redirect).","Use waitForLoadState('load') or 'networkidle' to settle before asserting.","Retry the goto once the page is stable."],"exampleFix":"// before\nawait page.goto('https://app.test/old'); // redirected mid-load -> throws\n// after\nawait page.goto('https://app.test/old');\nawait page.waitForURL('https://app.test/new');","handlingStrategy":"retry","validationCode":"// Settle before navigating\nawait page.waitForLoadState('networkidle');\nawait page.goto(url);","typeGuard":"function isNavigationInterrupted(e: unknown) {\n  return e instanceof Error && /interrupted by another navigation/i.test(e.message);\n}","tryCatchPattern":"try {\n  await page.goto(url);\n} catch (e) {\n  if (isNavigationInterrupted(e)) { await page.waitForLoadState('load'); return; }\n  throw e;\n}","preventionTips":["Prefer waitForURL for redirect-heavy flows.","Stabilize client-side redirect sources before the test."],"tags":["navigation","race","redirect"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}