{"record":{"id":"4dfe267b2df59aa6","repo":"GoogleChrome/lighthouse","slug":"gatherer-for-artifactdefn-id-did-not-provide-a","errorCode":null,"errorMessage":"Gatherer for ${artifactDefn.id} did not provide a meta object.","messagePattern":"Gatherer for (.+?) did not provide a meta object\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/config/validation.js","lineNumber":61,"sourceCode":"  }\n  if (!pluginName.startsWith('lighthouse-plugin-')) {\n    throw new Error(`plugin name '${pluginName}' does not start with 'lighthouse-plugin-'`);\n  }\n\n  if (config.categories?.[pluginName]) {\n    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\n  }\n}\n\n/**\n * 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","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/GoogleChrome/lighthouse/blob/9515cd4e58ebed69f78742d932b501c2cab8ad8f/core/config/validation.js#L43-L79","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Extend BaseGatherer and keep meta as an object: meta = {supportedModes: ['snapshot']}.","Do not reassign meta to a non-object; only set its supportedModes/dependencies.","If not extending BaseGatherer, define meta as an object literal on the class."],"exampleFix":"// before\nclass MyGatherer extends BaseGatherer {\n  meta = null;\n  getArtifact() {...}\n}\n// after\nclass MyGatherer extends BaseGatherer {\n  meta = {supportedModes: ['snapshot']};\n  getArtifact() {...}\n}","handlingStrategy":"type-guard","validationCode":"function assertGathererMeta(g) {\n  if (typeof g.meta !== 'object' || g.meta === null) {\n    throw new TypeError(`Gatherer ${g.constructor.name} needs a meta object`);\n  }\n}","typeGuard":"function hasGathererMeta(g) {\n  return typeof g === 'object' && g !== null && typeof g.meta === 'object' && g.meta !== null;\n}","tryCatchPattern":"try { new Config(config, {configPath}); }\ncatch (e) { if (/did not provide a meta object/.test(e.message)) console.error('Add meta = {supportedModes:[...]} to gatherer'); throw e; }","preventionTips":["Always extend BaseGatherer so meta defaults to an object.","Never reassign meta to null or a non-object.","Unit-test gatherers by instantiating and checking typeof instance.meta."],"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"}