{"record":{"id":"f49c89b95ded0973","repo":"GoogleChrome/lighthouse","slug":"onlycategories-cannot-be-an-empty-array","errorCode":null,"errorMessage":"onlyCategories cannot be an empty array.","messagePattern":"onlyCategories cannot be an empty array\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"core/config/filters.js","lineNumber":269,"sourceCode":"    categories,\n  };\n}\n\n/**\n * Filters a config's artifacts, audits, and categories down to the requested set.\n * Skip audits overrides inclusion via `onlyAudits`/`onlyCategories`.\n *\n * @param {LH.Config.ResolvedConfig} resolvedConfig\n * @param {Pick<LH.Config.Settings, 'onlyAudits'|'onlyCategories'|'skipAudits'>} filters\n * @return {LH.Config.ResolvedConfig}\n */\nfunction filterConfigByExplicitFilters(resolvedConfig, filters) {\n  const {onlyAudits, onlyCategories, skipAudits} = filters;\n  if (onlyAudits && !onlyAudits.length) {\n    throw new Error(`onlyAudits cannot be an empty array.`);\n  }\n  if (onlyCategories && !onlyCategories.length) {\n    throw new Error(`onlyCategories cannot be an empty array.`);\n  }\n\n  errorOnUnknownOnlyCategories(resolvedConfig.categories, onlyCategories);\n\n  let baseAuditIds = getAuditIdsInCategories(resolvedConfig.categories, undefined);\n  if (onlyCategories) {\n    baseAuditIds = getAuditIdsInCategories(resolvedConfig.categories, onlyCategories);\n  } else if (onlyAudits) {\n    baseAuditIds = new Set();\n  } else if (!resolvedConfig.categories || !Object.keys(resolvedConfig.categories).length) {\n    baseAuditIds = new Set(resolvedConfig.audits?.map(audit => audit.implementation.meta.id));\n  }\n\n  const auditIdsToKeep = new Set(\n    [\n      ...baseAuditIds, // Start with our base audits.\n      ...(onlyAudits || []), // Additionally include the opt-in audits from `onlyAudits`.\n      ...filterResistantAuditIds, // Always include any filter-resistant audits.","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/GoogleChrome/lighthouse/blob/9515cd4e58ebed69f78742d932b501c2cab8ad8f/core/config/filters.js#L251-L287","documentation":"Thrown by filterConfigByExplicitFilters in filters.js. Like onlyAudits, settings.onlyCategories may be null/undefined but must not be an empty array. An empty onlyCategories would request no categories, which Lighthouse treats as a misconfiguration and rejects immediately.","triggerScenarios":"flags.onlyCategories = [] (e.g. from an empty selection). onlyCategories && !onlyCategories.length is true, so filters.js:269 throws.","commonSituations":"UI-driven category selection with nothing chosen. Programmatic default of [] instead of undefined. Spreading an empty list.","solutions":["Use undefined/null to mean 'all categories': const onlyCategories = list.length ? list : undefined.","Require the user to pick at least one category before running."],"exampleFix":"// before\nconst flags = {onlyCategories: picked}; // picked === []\n// after\nconst flags = {onlyCategories: picked.length ? picked : undefined};","handlingStrategy":"validation","validationCode":"if (Array.isArray(flags.onlyCategories) && flags.onlyCategories.length === 0) {\n  flags.onlyCategories = undefined;\n}","typeGuard":"function onlyCategoriesIsValid(v) { return v == null || (Array.isArray(v) && v.length > 0); }","tryCatchPattern":"try { await lighthouse(url, flags); }\ncatch (e) { if (/onlyCategories cannot be an empty array/.test(e.message)) { flags.onlyCategories = undefined; } throw e; }","preventionTips":["Treat 'no selection' as undefined rather than [].","Default dynamically-built filter arrays to null when empty."],"tags":["config","lighthouse","filters","validation","categories"],"backgroundTag":null,"analyzedSha":"9515cd4e58ebed69f78742d932b501c2cab8ad8f","analyzedAt":"2026-08-13T06:28:10.346Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}