GoogleChrome/lighthouse · error · Error

${pluginName} is not defined as an object.

Error message

${pluginName} is not defined as an object.

What it means

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.

Source

Thrown at core/config/config-plugin.js:229

        title,
        description,
      };
    });
    return parsedGroupsJson;
  }

  /**
   * Extracts and validates a config from the provided plugin input, throwing
   * if it deviates from the expected object shape.
   * @param {unknown} pluginJson
   * @param {string} pluginName
   * @return {LH.Config}
   */
  static parsePlugin(pluginJson, pluginName) {
    // Clone to prevent modifications of original and to deactivate any live properties.
    pluginJson = JSON.parse(JSON.stringify(pluginJson));
    if (!isObjectOfUnknownProperties(pluginJson)) {
      throw new Error(`${pluginName} is not defined as an object.`);
    }

    const {
      audits: pluginAuditsJson,
      category: pluginCategoryJson,
      groups: pluginGroupsJson,
      ...invalidRest
    } = pluginJson;

    assertNoExcessProperties(invalidRest, pluginName);

    return {
      audits: ConfigPlugin._parseAuditsList(pluginAuditsJson, pluginName),
      categories: {
        [pluginName]: ConfigPlugin._parseCategory(pluginCategoryJson, pluginName),
      },
      groups: ConfigPlugin._parseGroups(pluginGroupsJson, pluginName),
    };

View on GitHub (pinned to 9515cd4e58)

Solutions

  1. Ensure the plugin's main export is an object with keys audits/category/groups: module.exports = {audits:[...], category:{...}, groups:{...}}.
  2. Check the plugin package.json 'main' field points to the file that exports the config object.
  3. Verify you are not importing a sub-file that exports a gatherer/audit class instead of the config.

Example fix

// before (plugin/index.js)
module.exports = [{path:'./audits/my-audit.js'}];
// after
module.exports = {
  audits: [{path:'./audits/my-audit.js'}],
  category: {title:'My Plugin', auditRefs:[{id:'my-audit', weight:1}]}
};
Defensive patterns

Strategy: validation

Validate before calling

function isPlainObject(v) { return typeof v === 'object' && v !== null && !Array.isArray(v); }
if (!isPlainObject(plugin)) throw new TypeError('plugin export must be an object {audits, category, groups}');

Type guard

function isPluginObject(v) {
  return typeof v === 'object' && v !== null && !Array.isArray(v);
}

Try / catch

try { const cfg = ConfigPlugin.parsePlugin(require(pluginName), pluginName); }
catch (e) { if (/is not defined as an object/.test(e.message)) console.error('Plugin main export must be a config object'); throw e; }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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