GoogleChrome/lighthouse · error

Gatherer for ${artifactDefn.id} did not provide a meta objec

Error message

Gatherer for ${artifactDefn.id} did not provide a meta object.

What it means

Thrown by assertValidArtifact in validation.js. Every gatherer instance must expose a 'meta' object (typeof 'object'). BaseGatherer provides meta = {supportedModes: []} by default; if a custom gatherer deletes meta or sets it to a non-object (string/null/undefined), this fails. meta carries supportedModes and dependency declarations Lighthouse relies on.

Source

Thrown at core/config/validation.js:61

  }
  if (!pluginName.startsWith('lighthouse-plugin-')) {
    throw new Error(`plugin name '${pluginName}' does not start with 'lighthouse-plugin-'`);
  }

  if (config.categories?.[pluginName]) {
    throw new Error(`plugin name '${pluginName}' not allowed because it is the id of a category already found in config`); // eslint-disable-line max-len
  }
}

/**
 * Throws an error if the provided object does not implement the required gatherer interface.
 * @param {LH.Config.AnyArtifactDefn} artifactDefn
 */
function assertValidArtifact(artifactDefn) {
  const gatherer = artifactDefn.gatherer.instance;

  if (typeof gatherer.meta !== 'object') {
    throw new Error(`Gatherer for ${artifactDefn.id} did not provide a meta object.`);
  }

  if (gatherer.meta.supportedModes.length === 0) {
    throw new Error(`Gatherer for ${artifactDefn.id} did not support any gather modes.`);
  }

  if (
    typeof gatherer.getArtifact !== 'function' ||
    gatherer.getArtifact === BaseGatherer.prototype.getArtifact
  ) {
    throw new Error(`Gatherer for ${artifactDefn.id} did not define a "getArtifact" method.`);
  }
}

/**
 * Throws an error if the provided object does not implement the required properties of an audit
 * definition.
 * @param {LH.Config.AuditDefn} auditDefinition

View on GitHub (pinned to 9515cd4e58)

Solutions

  1. Extend BaseGatherer and keep meta as an object: meta = {supportedModes: ['snapshot']}.
  2. Do not reassign meta to a non-object; only set its supportedModes/dependencies.
  3. If not extending BaseGatherer, define meta as an object literal on the class.

Example fix

// before
class MyGatherer extends BaseGatherer {
  meta = null;
  getArtifact() {...}
}
// after
class MyGatherer extends BaseGatherer {
  meta = {supportedModes: ['snapshot']};
  getArtifact() {...}
}
Defensive patterns

Strategy: type-guard

Validate before calling

function assertGathererMeta(g) {
  if (typeof g.meta !== 'object' || g.meta === null) {
    throw new TypeError(`Gatherer ${g.constructor.name} needs a meta object`);
  }
}

Type guard

function hasGathererMeta(g) {
  return typeof g === 'object' && g !== null && typeof g.meta === 'object' && g.meta !== null;
}

Try / catch

try { new Config(config, {configPath}); }
catch (e) { if (/did not provide a meta object/.test(e.message)) console.error('Add meta = {supportedModes:[...]} to gatherer'); throw e; }

Prevention

When it happens

Trigger: A custom gatherer class sets meta = null or removes the meta property, or assigns meta = 'snapshot'. assertValidArtifact sees typeof gatherer.meta !== 'object' and validation.js:61 throws.

Common situations: Extending BaseGatherer but overriding meta incorrectly. Assigning a static string instead of an object. A gatherer written for an older API that lacked meta. Transpilation/bundling stripping class fields.

Related errors


AI-assisted analysis of GoogleChrome/lighthouse@9515cd4e58 (2026-08-13). Data as JSON: /api/errors/4dfe267b2df59aa6. Report an issue: GitHub.