GoogleChrome/lighthouse · error · Error
onlyCategories cannot be an empty array.
Error message
onlyCategories cannot be an empty array.
What it means
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.
Source
Thrown at core/config/filters.js:269
categories,
};
}
/**
* Filters a config's artifacts, audits, and categories down to the requested set.
* Skip audits overrides inclusion via `onlyAudits`/`onlyCategories`.
*
* @param {LH.Config.ResolvedConfig} resolvedConfig
* @param {Pick<LH.Config.Settings, 'onlyAudits'|'onlyCategories'|'skipAudits'>} filters
* @return {LH.Config.ResolvedConfig}
*/
function filterConfigByExplicitFilters(resolvedConfig, filters) {
const {onlyAudits, onlyCategories, skipAudits} = filters;
if (onlyAudits && !onlyAudits.length) {
throw new Error(`onlyAudits cannot be an empty array.`);
}
if (onlyCategories && !onlyCategories.length) {
throw new Error(`onlyCategories cannot be an empty array.`);
}
errorOnUnknownOnlyCategories(resolvedConfig.categories, onlyCategories);
let baseAuditIds = getAuditIdsInCategories(resolvedConfig.categories, undefined);
if (onlyCategories) {
baseAuditIds = getAuditIdsInCategories(resolvedConfig.categories, onlyCategories);
} else if (onlyAudits) {
baseAuditIds = new Set();
} else if (!resolvedConfig.categories || !Object.keys(resolvedConfig.categories).length) {
baseAuditIds = new Set(resolvedConfig.audits?.map(audit => audit.implementation.meta.id));
}
const auditIdsToKeep = new Set(
[
...baseAuditIds, // Start with our base audits.
...(onlyAudits || []), // Additionally include the opt-in audits from `onlyAudits`.
...filterResistantAuditIds, // Always include any filter-resistant audits.View on GitHub (pinned to 9515cd4e58)
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.
Example fix
// before
const flags = {onlyCategories: picked}; // picked === []
// after
const flags = {onlyCategories: picked.length ? picked : undefined}; Defensive patterns
Strategy: validation
Validate before calling
if (Array.isArray(flags.onlyCategories) && flags.onlyCategories.length === 0) {
flags.onlyCategories = undefined;
} Type guard
function onlyCategoriesIsValid(v) { return v == null || (Array.isArray(v) && v.length > 0); } Try / catch
try { await lighthouse(url, flags); }
catch (e) { if (/onlyCategories cannot be an empty array/.test(e.message)) { flags.onlyCategories = undefined; } throw e; } Prevention
- Treat 'no selection' as undefined rather than [].
- Default dynamically-built filter arrays to null when empty.
When it happens
Trigger: flags.onlyCategories = [] (e.g. from an empty selection). onlyCategories && !onlyCategories.length is true, so filters.js:269 throws.
Common situations: UI-driven category selection with nothing chosen. Programmatic default of [] instead of undefined. Spreading an empty list.
Related errors
- unrecognized category in 'onlyCategories': ${unknown.join(',
- onlyAudits cannot be an empty array.
- plugin name '${pluginName}' not allowed because it is the id
- ${pluginName} has an invalid category description.
- ${pluginName} has an invalid category manualDescription.
AI-assisted analysis of GoogleChrome/lighthouse@9515cd4e58 (2026-08-13).
Data as JSON: /api/errors/f49c89b95ded0973.
Report an issue: GitHub.