{"record":{"id":"f41c66a6c263a7c1","repo":"GoogleChrome/lighthouse","slug":"no-timespan-in-progress","errorCode":null,"errorMessage":"No timespan in progress","messagePattern":"No timespan in progress","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"core/user-flow.js","lineNumber":208,"sourceCode":"\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};\n  }\n\n  async endTimespan() {\n    if (!this.currentTimespan) throw new Error('No timespan in progress');\n    if (this.currentNavigation) throw new Error('Navigation already in progress');\n\n    const {timespan, flags} = this.currentTimespan;\n    const gatherResult = await timespan.endTimespanGather();\n    this.currentTimespan = undefined;\n\n    this._addGatherStep(gatherResult, flags);\n  }\n\n  /**\n   * @param {LH.UserFlow.StepFlags} [flags]\n   */\n  async snapshot(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","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/GoogleChrome/lighthouse/blob/9515cd4e58ebed69f78742d932b501c2cab8ad8f/core/user-flow.js#L190-L226","documentation":"State-machine guard in UserFlow.endTimespan(). Requires currentTimespan to be set. Fires when endTimespan() is called without a prior startTimespan(), or when endTimespan() is called twice (the second call finds currentTimespan already cleared to undefined at line 213).","triggerScenarios":"Calling flow.endTimespan() when flow.currentTimespan is undefined. Happens when startTimespan() was never called, or after endTimespan() already completed and cleared the state.","commonSituations":"Forgot to call startTimespan() first. Double-calling endTimespan(). Calling endTimespan() by mistake instead of endNavigation(). Exception in a try/finally that caused endTimespan to run after it was already ended.","solutions":["Ensure startTimespan() was called before endTimespan()","Check flow.currentTimespan is set before calling endTimespan()","Do not call endTimespan() twice — guard with a currentTimespan check"],"exampleFix":"// before — endTimespan without startTimespan\nawait flow.endTimespan(); // throws\n\n// after — start timespan first\nawait flow.startTimespan();\n// ... interactions ...\nawait flow.endTimespan();","handlingStrategy":"validation","validationCode":"if (!flow.currentTimespan) {\n  console.error('No timespan in progress — did you call startTimespan()?');\n  return;\n}\nawait flow.endTimespan();","typeGuard":"/** @param {UserFlow} flow @returns {boolean} */\nfunction canEndTimespan(flow) {\n  return flow.currentTimespan != null && flow.currentNavigation == null;\n}","tryCatchPattern":null,"preventionTips":["Always call startTimespan() before endTimespan()","Never call endTimespan() twice without an intervening startTimespan","Check flow.currentTimespan before calling endTimespan()"],"tags":["user-flow","state-machine","timespan","ordering"],"backgroundTag":null,"analyzedSha":"9515cd4e58ebed69f78742d932b501c2cab8ad8f","analyzedAt":"2026-08-13T06:28:10.346Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}