GoogleChrome/lighthouse · error · Error
Navigation already in progress
Error message
Navigation already in progress
What it means
State-machine guard in UserFlow.navigate(). navigate() requires currentNavigation to be undefined. This throw fires when a navigation is already in progress — startNavigation() was called but endNavigation() has not completed. Since startNavigation() internally calls navigate(), this also guards against overlapping startNavigation calls.
Source
Thrown at core/user-flow.js:128
* @param {LH.Gatherer.GatherResult} gatherResult
* @param {LH.UserFlow.StepFlags} [flags]
*/
_addGatherStep(gatherResult, flags) {
const gatherStep = {
artifacts: gatherResult.artifacts,
flags,
};
this._gatherSteps.push(gatherStep);
this._gatherStepRunnerOptions.set(gatherStep, gatherResult.runnerOptions);
}
/**
* @param {LH.NavigationRequestor} requestor
* @param {LH.UserFlow.StepFlags} [flags]
*/
async navigate(requestor, flags) {
if (this.currentTimespan) throw new Error('Timespan already in progress');
if (this.currentNavigation) throw new Error('Navigation already in progress');
const nextFlags = this._getNextNavigationFlags(flags);
const gatherResult = await navigationGather(this._page, requestor, {
config: this._options?.config,
flags: nextFlags,
});
this._addGatherStep(gatherResult, nextFlags);
}
/**
* This is an alternative to `navigate()` that can be used to analyze a navigation triggered by user interaction.
* For more on user triggered navigations, see https://github.com/GoogleChrome/lighthouse/blob/main/docs/user-flows.md#triggering-a-navigation-via-user-interactions.
*
* @param {LH.UserFlow.StepFlags} [stepOptions]
*/
async startNavigation(stepOptions) {
/** @type {(value: () => void) => void} */View on GitHub (pinned to 9515cd4e58)
Solutions
- Call flow.endNavigation() before starting a new navigation
- Ensure the page navigation actually occurs between startNavigation and endNavigation — endNavigation awaits the result
- Wrap navigation logic in try/finally to guarantee endNavigation() runs
Example fix
// before — overlapping navigations await flow.startNavigation(); // ... user clicks a link triggering navigation ... await flow.startNavigation(); // throws // after — end first navigation await flow.startNavigation(); // ... user clicks a link triggering navigation ... await flow.endNavigation(); await flow.startNavigation();
Defensive patterns
Strategy: validation
Validate before calling
if (flow.currentNavigation) {
await flow.endNavigation();
}
await flow.navigate(url); Type guard
/** @param {UserFlow} flow @returns {boolean} */
function isNavigationActive(flow) {
return flow.currentNavigation != null;
} Try / catch
try {
await flow.navigate(url);
} catch (e) {
if (e.message === 'Navigation already in progress') {
await flow.endNavigation();
await flow.navigate(url);
} else throw e;
} Prevention
- Always pair startNavigation() with endNavigation() using try/finally
- Ensure the page navigation actually occurs before calling endNavigation
- Check flow.currentNavigation before starting a new navigation
When it happens
Trigger: Calling flow.navigate(url) or flow.startNavigation() after a prior flow.startNavigation() without calling flow.endNavigation() first. The currentNavigation property is still set from the prior startNavigation call.
Common situations: Forgot to call endNavigation() after startNavigation(). The user interaction that triggers the navigation was never performed, so endNavigation was never called. Calling navigate() (the synchronous variant) while an async startNavigation flow is pending.
Related errors
- Timespan already in progress
- No navigation in progress
- No timespan in progress
- NO_DCL
- unexpected response: ${response.statusCode} ${response.statu
AI-assisted analysis of GoogleChrome/lighthouse@9515cd4e58 (2026-08-13).
Data as JSON: /api/errors/baa94e24cfe445f2.
Report an issue: GitHub.