{"record":{"id":"1d5bfa9006d8f455","repo":"GoogleChrome/lighthouse","slug":"gatherer-for-artifactdefn-id-did-not-define-a","errorCode":null,"errorMessage":"Gatherer for ${artifactDefn.id} did not define a \"getArtifact\" method.","messagePattern":"Gatherer for (.+?) did not define a \"getArtifact\" method\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/config/validation.js","lineNumber":72,"sourceCode":" * Throws an error if the provided object does not implement the required gatherer interface.\n * @param {LH.Config.AnyArtifactDefn} artifactDefn\n */\nfunction assertValidArtifact(artifactDefn) {\n  const gatherer = artifactDefn.gatherer.instance;\n\n  if (typeof gatherer.meta !== 'object') {\n    throw new Error(`Gatherer for ${artifactDefn.id} did not provide a meta object.`);\n  }\n\n  if (gatherer.meta.supportedModes.length === 0) {\n    throw new Error(`Gatherer for ${artifactDefn.id} did not support any gather modes.`);\n  }\n\n  if (\n    typeof gatherer.getArtifact !== 'function' ||\n    gatherer.getArtifact === BaseGatherer.prototype.getArtifact\n  ) {\n    throw new Error(`Gatherer for ${artifactDefn.id} did not define a \"getArtifact\" method.`);\n  }\n}\n\n/**\n * Throws an error if the provided object does not implement the required properties of an audit\n * definition.\n * @param {LH.Config.AuditDefn} auditDefinition\n */\nfunction assertValidAudit(auditDefinition) {\n  const {implementation, path: auditPath} = auditDefinition;\n  const auditName = auditPath ||\n    implementation?.meta?.id ||\n    'Unknown audit';\n\n  if (typeof implementation.audit !== 'function' || implementation.audit === Audit.audit) {\n    throw new Error(`${auditName} has no audit() method.`);\n  }\n","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/GoogleChrome/lighthouse/blob/9515cd4e58ebed69f78742d932b501c2cab8ad8f/core/config/validation.js#L54-L90","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Implement getArtifact(passContext) in your gatherer class returning the artifact (or a Promise of it).","Make sure you actually override the method name (exact spelling: getArtifact).","Confirm your class extends BaseGatherer so the prototype comparison is meaningful."],"exampleFix":"// before\nclass MyGatherer extends BaseGatherer {\n  meta = {supportedModes: ['snapshot']};\n  // no getArtifact defined\n}\n// after\nclass MyGatherer extends BaseGatherer {\n  meta = {supportedModes: ['snapshot']};\n  async getArtifact(ctx) {\n    return {value: await ctx.driver.evaluate(...)};\n  }\n}","handlingStrategy":"type-guard","validationCode":"const BaseGatherer = require('lighthouse/core/gather/base-gatherer.js').default;\nfunction assertGetArtifact(g) {\n  if (typeof g.getArtifact !== 'function' || g.getArtifact === BaseGatherer.prototype.getArtifact) {\n    throw new TypeError(`Gatherer must override getArtifact`);\n  }\n}","typeGuard":"function implementsGetArtifact(g, Base) {\n  return typeof g.getArtifact === 'function' && g.getArtifact !== Base.prototype.getArtifact;\n}","tryCatchPattern":"try { new Config(config, {configPath}); }\ncatch (e) { if (/did not define a .getArtifact. method/.test(e.message)) console.error('Implement getArtifact()'); throw e; }","preventionTips":["Implement getArtifact(passContext) in every gatherer subclass.","Name the method exactly 'getArtifact'.","Ensure it overrides (not just shadows) the base method."],"tags":["config","lighthouse","gatherer","validation","artifact"],"backgroundTag":null,"analyzedSha":"9515cd4e58ebed69f78742d932b501c2cab8ad8f","analyzedAt":"2026-08-13T06:28:10.346Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}