{"record":{"id":"f6510bee40d386c1","repo":"GoogleChrome/lighthouse","slug":"no-navigation-in-progress","errorCode":null,"errorMessage":"No navigation in progress","messagePattern":"No navigation in progress","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"core/user-flow.js","lineNumber":186,"sourceCode":"      } else {\n        // If the navigation has not started, reject the `navigationSetupPromise` so the error throws when it is awaited in `startNavigation`.\n        rejectDuringSetup(err);\n      }\n    });\n\n    const continueNavigation = await navigationSetupPromise;\n\n    async function continueAndAwaitResult() {\n      continueNavigation();\n      await navigationResultPromise;\n    }\n\n    this.currentNavigation = {continueAndAwaitResult};\n  }\n\n  async endNavigation() {\n    if (this.currentTimespan) throw new Error('Timespan already in progress');\n    if (!this.currentNavigation) throw new Error('No navigation in progress');\n    await this.currentNavigation.continueAndAwaitResult();\n    this.currentNavigation = undefined;\n  }\n\n  /**\n   * @param {LH.UserFlow.StepFlags} [flags]\n   */\n  async startTimespan(flags) {\n    if (this.currentTimespan) throw new Error('Timespan already in progress');\n    if (this.currentNavigation) throw new Error('Navigation already in progress');\n\n    const nextFlags = this._getNextFlags(flags);\n\n    const timespan = await startTimespanGather(this._page, {\n      config: this._options?.config,\n      flags: nextFlags,\n    });\n    this.currentTimespan = {timespan, flags: nextFlags};","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/GoogleChrome/lighthouse/blob/9515cd4e58ebed69f78742d932b501c2cab8ad8f/core/user-flow.js#L168-L204","documentation":"State-machine guard in UserFlow.endNavigation(). This method requires a navigation to be active (currentNavigation must be set). The throw fires when endNavigation() is called without a prior startNavigation(), or after the navigation was already ended.","triggerScenarios":"Calling flow.endNavigation() when flow.currentNavigation is undefined. This happens when startNavigation() was never called, or when endNavigation() is called twice (the second call finds currentNavigation already cleared to undefined at line 188).","commonSituations":"Calling endNavigation() by mistake instead of endTimespan(). Double-calling endNavigation(). Forgot to call startNavigation() first. The navigation flow was structured as navigate() (synchronous) but endNavigation() was called expecting the startNavigation/endNavigation pattern.","solutions":["Ensure startNavigation() was called before endNavigation()","Check flow.currentNavigation is set before calling endNavigation()","Do not call endNavigation() twice — it clears currentNavigation after the first call"],"exampleFix":"// before — endNavigation without startNavigation\nawait flow.endNavigation(); // throws\n\n// after — start navigation first\nawait flow.startNavigation();\n// ... trigger navigation ...\nawait flow.endNavigation();","handlingStrategy":"validation","validationCode":"if (!flow.currentNavigation) {\n  console.error('No navigation in progress — did you call startNavigation()?');\n  return;\n}\nawait flow.endNavigation();","typeGuard":"/** @param {UserFlow} flow @returns {boolean} */\nfunction canEndNavigation(flow) {\n  return flow.currentNavigation != null && flow.currentTimespan == null;\n}","tryCatchPattern":null,"preventionTips":["Always call startNavigation() before endNavigation()","Never call endNavigation() twice — track the state yourself","Check flow.currentNavigation before calling endNavigation()"],"tags":["user-flow","state-machine","navigation","ordering"],"backgroundTag":null,"analyzedSha":"9515cd4e58ebed69f78742d932b501c2cab8ad8f","analyzedAt":"2026-08-13T06:28:10.346Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}