{"record":{"id":"1c48e1d4cf32de93","repo":"GoogleChrome/lighthouse","slug":"pluginname-is-not-defined-as-an-object","errorCode":null,"errorMessage":"${pluginName} is not defined as an object.","messagePattern":"(.+?) is not defined as an object\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"core/config/config-plugin.js","lineNumber":229,"sourceCode":"        title,\n        description,\n      };\n    });\n    return parsedGroupsJson;\n  }\n\n  /**\n   * Extracts and validates a config from the provided plugin input, throwing\n   * if it deviates from the expected object shape.\n   * @param {unknown} pluginJson\n   * @param {string} pluginName\n   * @return {LH.Config}\n   */\n  static parsePlugin(pluginJson, pluginName) {\n    // Clone to prevent modifications of original and to deactivate any live properties.\n    pluginJson = JSON.parse(JSON.stringify(pluginJson));\n    if (!isObjectOfUnknownProperties(pluginJson)) {\n      throw new Error(`${pluginName} is not defined as an object.`);\n    }\n\n    const {\n      audits: pluginAuditsJson,\n      category: pluginCategoryJson,\n      groups: pluginGroupsJson,\n      ...invalidRest\n    } = pluginJson;\n\n    assertNoExcessProperties(invalidRest, pluginName);\n\n    return {\n      audits: ConfigPlugin._parseAuditsList(pluginAuditsJson, pluginName),\n      categories: {\n        [pluginName]: ConfigPlugin._parseCategory(pluginCategoryJson, pluginName),\n      },\n      groups: ConfigPlugin._parseGroups(pluginGroupsJson, pluginName),\n    };","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/GoogleChrome/lighthouse/blob/9515cd4e58ebed69f78742d932b501c2cab8ad8f/core/config/config-plugin.js#L211-L247","documentation":"Thrown by ConfigPlugin.parsePlugin, the top-level plugin validator. The plugin's module export (pluginJson) must be a plain object (isObjectOfUnknownProperties: typeof 'object', not null, not array). If the plugin exports anything else (a string, array, number, null, or a function), parsing aborts here.","triggerScenarios":"A plugin package's main module does `module.exports = [...]` or `module.exports = 'config'` or `module.exports = null`. parsePlugin clones then checks the shape; a non-object triggers config-plugin.js:229.","commonSituations":"Plugin module exports the wrong shape (e.g. exports an array of audits instead of {audits, category, groups}). Default export accidentally set to null. Plugin written for a different Lighthouse plugin API version.","solutions":["Ensure the plugin's main export is an object with keys audits/category/groups: module.exports = {audits:[...], category:{...}, groups:{...}}.","Check the plugin package.json 'main' field points to the file that exports the config object.","Verify you are not importing a sub-file that exports a gatherer/audit class instead of the config."],"exampleFix":"// before (plugin/index.js)\nmodule.exports = [{path:'./audits/my-audit.js'}];\n// after\nmodule.exports = {\n  audits: [{path:'./audits/my-audit.js'}],\n  category: {title:'My Plugin', auditRefs:[{id:'my-audit', weight:1}]}\n};","handlingStrategy":"validation","validationCode":"function isPlainObject(v) { return typeof v === 'object' && v !== null && !Array.isArray(v); }\nif (!isPlainObject(plugin)) throw new TypeError('plugin export must be an object {audits, category, groups}');","typeGuard":"function isPluginObject(v) {\n  return typeof v === 'object' && v !== null && !Array.isArray(v);\n}","tryCatchPattern":"try { const cfg = ConfigPlugin.parsePlugin(require(pluginName), pluginName); }\ncatch (e) { if (/is not defined as an object/.test(e.message)) console.error('Plugin main export must be a config object'); throw e; }","preventionTips":["Ensure the plugin package main exports {audits, category, groups}.","Verify package.json 'main' points to the config-exporting file.","Write a smoke test that loads the plugin export and checks typeof === 'object'."],"tags":["config","lighthouse","plugin","validation"],"backgroundTag":null,"analyzedSha":"9515cd4e58ebed69f78742d932b501c2cab8ad8f","analyzedAt":"2026-08-13T06:28:10.346Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}