{"record":{"id":"cfaa9ca53f64f7bf","repo":"GoogleChrome/lighthouse","slug":"auditname-has-no-audit-method","errorCode":null,"errorMessage":"${auditName} has no audit() method.","messagePattern":"(.+?) has no audit\\(\\) method\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/config/validation.js","lineNumber":88,"sourceCode":"    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\n  if (typeof implementation.meta.id !== 'string') {\n    throw new Error(`${auditName} has no meta.id property, or the property is not a string.`);\n  }\n\n  if (!i18n.isStringOrIcuMessage(implementation.meta.title)) {\n    throw new Error(`${auditName} has no meta.title property, or the property is not a string.`);\n  }\n\n  // If it'll have a ✔ or ✖ displayed alongside the result, it should have failureTitle\n  const scoreDisplayMode = implementation.meta.scoreDisplayMode || Audit.SCORING_MODES.BINARY;\n  if (\n    !i18n.isStringOrIcuMessage(implementation.meta.failureTitle) &&\n    scoreDisplayMode === Audit.SCORING_MODES.BINARY\n  ) {\n    throw new Error(`${auditName} has no meta.failureTitle and should.`);\n  }","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/GoogleChrome/lighthouse/blob/9515cd4e58ebed69f78742d932b501c2cab8ad8f/core/config/validation.js#L70-L106","documentation":"Thrown by assertValidAudit in validation.js. An audit implementation must provide an 'audit' method that is a function AND must override Audit.audit (the base placeholder). The check `implementation.audit === Audit.audit` catches subclasses that extend Audit but never define their own audit logic. auditName is the audit path or meta.id for context.","triggerScenarios":"A custom audit class extends Audit but does not declare a static/prototype audit method, so implementation.audit === Audit.audit. Or audit is set to a non-function. validation.js:88 throws.","commonSituations":"Writing a new audit and forgetting the audit() method. Copying an audit scaffold without filling in audit(). Naming the method differently (e.g. 'run' from an older API).","solutions":["Define a static audit(artifacts, context) method on your audit class returning {score, ...}.","Ensure the method name is exactly 'audit'.","Confirm your class extends Audit so the override check is valid."],"exampleFix":"// before\nclass MyAudit extends Audit {\n  static get meta() { return {id:'my-audit', title:'X', description:'Y', requiredArtifacts:[]}; }\n  // no audit() method\n}\n// after\nclass MyAudit extends Audit {\n  static get meta() { return {id:'my-audit', title:'X', description:'Y', requiredArtifacts:[]}; }\n  static audit(artifacts) {\n    return {score: artifacts.X ? 1 : 0};\n  }\n}","handlingStrategy":"type-guard","validationCode":"const {Audit} = require('lighthouse/core/audits/audit.js');\nfunction assertAuditMethod(impl) {\n  if (typeof impl.audit !== 'function' || impl.audit === Audit.audit) {\n    throw new TypeError(`Audit must override audit()`);\n  }\n}","typeGuard":"function implementsAudit(impl, Audit) {\n  return typeof impl.audit === 'function' && impl.audit !== Audit.audit;\n}","tryCatchPattern":"try { new Config(config, {configPath}); }\ncatch (e) { if (/has no audit\\(\\) method/.test(e.message)) console.error('Define static audit() on the audit class'); throw e; }","preventionTips":["Define a static audit(artifacts, context) on every audit class.","Name it exactly 'audit'.","Smoke-test audits by checking the method is not the base placeholder."],"tags":["config","lighthouse","audit","validation"],"backgroundTag":null,"analyzedSha":"9515cd4e58ebed69f78742d932b501c2cab8ad8f","analyzedAt":"2026-08-13T06:28:10.346Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}