{"record":{"id":"e0e161dff20559ab","repo":"GoogleChrome/lighthouse","slug":"unsupported-gather-mode","errorCode":null,"errorMessage":"Unsupported gather mode","messagePattern":"Unsupported gather mode","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"core/user-flow.js","lineNumber":292,"sourceCode":"/**\n * @param {LH.UserFlow.StepFlags|undefined} flags\n * @param {LH.Artifacts} artifacts\n * @return {string}\n */\nfunction getStepName(flags, artifacts) {\n  if (flags?.name) return flags.name;\n\n  const {locale} = artifacts.settings;\n  const shortUrl = shortenUrl(artifacts.URL.finalDisplayedUrl);\n  switch (artifacts.GatherContext.gatherMode) {\n    case 'navigation':\n      return translate(UIStrings.defaultNavigationName, {url: shortUrl}, locale);\n    case 'timespan':\n      return translate(UIStrings.defaultTimespanName, {url: shortUrl}, locale);\n    case 'snapshot':\n      return translate(UIStrings.defaultSnapshotName, {url: shortUrl}, locale);\n    default:\n      throw new Error('Unsupported gather mode');\n  }\n}\n\n/**\n * @param {string|undefined} name\n * @param {LH.UserFlow.GatherStep[]} gatherSteps\n * @return {string}\n */\nfunction getFlowName(name, gatherSteps) {\n  if (name) return name;\n\n  const firstArtifacts = gatherSteps[0].artifacts;\n  const {locale} = firstArtifacts.settings;\n  const url = new URL(firstArtifacts.URL.finalDisplayedUrl).hostname;\n  return translate(UIStrings.defaultFlowName, {url}, locale);\n}\n\n/**","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/GoogleChrome/lighthouse/blob/9515cd4e58ebed69f78742d932b501c2cab8ad8f/core/user-flow.js#L274-L310","documentation":"Thrown by getStepName() when generating a display name for a flow step. It switches on artifacts.GatherContext.gatherMode, supporting 'navigation', 'timespan', and 'snapshot'. Any other value — including undefined, null, or a future gather mode — hits the default branch and throws. This is an internal invariant: all gather steps should have a valid gatherMode set by the gatherer runners.","triggerScenarios":"Called from auditGatherSteps (user-flow.js:323) during createFlowResult(). Fires when a gather step's artifacts.GatherContext.gatherMode is not 'navigation', 'timespan', or 'snapshot'. This can occur with manually constructed gather steps (e.g., from createArtifactsJson deserialization with corrupted data), mocked test artifacts, or artifacts from an incompatible Lighthouse version that introduced a new gather mode.","commonSituations":"Manually constructing gather steps without proper GatherContext. Deserializing artifacts from a flow saved by a different Lighthouse version. Test mocks with incomplete artifacts.GatherContext. Corrupted or hand-edited flow artifacts JSON.","solutions":["Create flow steps only through the UserFlow API (navigate/startTimespan+endTimespan/snapshot) which sets GatherContext correctly","If loading saved artifacts, validate each step's artifacts.GatherContext.gatherMode is one of the three supported values before calling createFlowResult","Ensure you're using a compatible Lighthouse version for both gathering and auditing"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const VALID_MODES = ['navigation', 'timespan', 'snapshot'];\nfor (const step of gatherSteps) {\n  const mode = step.artifacts?.GatherContext?.gatherMode;\n  if (!VALID_MODES.includes(mode)) {\n    throw new Error(`Invalid gather mode: ${mode} — steps must be created via the UserFlow API`);\n  }\n}","typeGuard":"/** @param {string} mode @returns {boolean} */\nfunction isValidGatherMode(mode) {\n  return mode === 'navigation' || mode === 'timespan' || mode === 'snapshot';\n}","tryCatchPattern":null,"preventionTips":["Create flow steps only through navigate(), startTimespan()/endTimespan(), or snapshot()","Validate GatherContext.gatherMode before calling createFlowResult or auditGatherSteps","Use the same Lighthouse version for gathering and auditing"],"tags":["user-flow","gather-mode","internal-invariant"],"backgroundTag":null,"analyzedSha":"9515cd4e58ebed69f78742d932b501c2cab8ad8f","analyzedAt":"2026-08-13T06:28:10.346Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}