GoogleChrome/lighthouse · error

Gatherer for ${artifactDefn.id} did not define a "getArtifac

Error message

Gatherer for ${artifactDefn.id} did not define a "getArtifact" method.

What it means

Thrown by assertValidArtifact in validation.js. Each artifact gatherer must implement getArtifact as an actual function and must OVERRIDE BaseGatherer.prototype.getArtifact (which is an empty placeholder). The check fails if getArtifact is not a function, or if it still equals the base no-op (i.e. the subclass never defined its own). This guarantees the gatherer produces an artifact.

Source

Thrown at core/config/validation.js:72

 * 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
 */
function assertValidAudit(auditDefinition) {
  const {implementation, path: auditPath} = auditDefinition;
  const auditName = auditPath ||
    implementation?.meta?.id ||
    'Unknown audit';

  if (typeof implementation.audit !== 'function' || implementation.audit === Audit.audit) {
    throw new Error(`${auditName} has no audit() method.`);
  }

View on GitHub (pinned to 9515cd4e58)

Solutions

  1. Implement getArtifact(passContext) in your gatherer class returning the artifact (or a Promise of it).
  2. Make sure you actually override the method name (exact spelling: getArtifact).
  3. Confirm your class extends BaseGatherer so the prototype comparison is meaningful.

Example fix

// before
class MyGatherer extends BaseGatherer {
  meta = {supportedModes: ['snapshot']};
  // no getArtifact defined
}
// after
class MyGatherer extends BaseGatherer {
  meta = {supportedModes: ['snapshot']};
  async getArtifact(ctx) {
    return {value: await ctx.driver.evaluate(...)};
  }
}
Defensive patterns

Strategy: type-guard

Validate before calling

const BaseGatherer = require('lighthouse/core/gather/base-gatherer.js').default;
function assertGetArtifact(g) {
  if (typeof g.getArtifact !== 'function' || g.getArtifact === BaseGatherer.prototype.getArtifact) {
    throw new TypeError(`Gatherer must override getArtifact`);
  }
}

Type guard

function implementsGetArtifact(g, Base) {
  return typeof g.getArtifact === 'function' && g.getArtifact !== Base.prototype.getArtifact;
}

Try / catch

try { new Config(config, {configPath}); }
catch (e) { if (/did not define a .getArtifact. method/.test(e.message)) console.error('Implement getArtifact()'); throw e; }

Prevention

When it happens

Trigger: A gatherer extends BaseGatherer but omits getArtifact (inherits the empty base method), so gatherer.getArtifact === BaseGatherer.prototype.getArtifact is true. Or getArtifact is set to a non-function. validation.js:72 throws.

Common situations: New gatherer that only implements legacy methods (e.g. startInstrumentation) but not getArtifact. Forgetting to rename an old 'afterPass'/'getArtifact' mismatch. Defining getArtifact as a property holding data instead of a method.

Related errors


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