{"record":{"id":"64341faf84ae8636","repo":"GoogleChrome/lighthouse","slug":"pluginname-has-a-group-not-defined-as-an-object","errorCode":null,"errorMessage":"${pluginName} has a group not defined as an object.","messagePattern":"(.+?) has a group not defined as an object\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"core/config/config-plugin.js","lineNumber":199,"sourceCode":"   * @param {string} pluginName\n   * @return {Record<string, LH.Config.GroupJson>|undefined}\n   */\n  static _parseGroups(groupsJson, pluginName) {\n    if (groupsJson === undefined) {\n      return undefined;\n    }\n\n    if (!isObjectOfUnknownProperties(groupsJson)) {\n      throw new Error(`${pluginName} groups json is not defined as an object.`);\n    }\n\n    const groups = Object.entries(groupsJson);\n\n    /** @type {Record<string, LH.Config.GroupJson>} */\n    const parsedGroupsJson = {};\n    groups.forEach(([groupId, groupJson]) => {\n      if (!isObjectOfUnknownProperties(groupJson)) {\n        throw new Error(`${pluginName} has a group not defined as an object.`);\n      }\n      const {title, description, ...invalidRest} = groupJson;\n      assertNoExcessProperties(invalidRest, pluginName, 'group');\n\n      if (!i18n.isStringOrIcuMessage(title)) {\n        throw new Error(`${pluginName} has an invalid group title.`);\n      }\n      if (!i18n.isStringOrIcuMessage(description) && description !== undefined) {\n        throw new Error(`${pluginName} has an invalid group description.`);\n      }\n      parsedGroupsJson[`${pluginName}-${groupId}`] = {\n        title,\n        description,\n      };\n    });\n    return parsedGroupsJson;\n  }\n","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/GoogleChrome/lighthouse/blob/9515cd4e58ebed69f78742d932b501c2cab8ad8f/core/config/config-plugin.js#L181-L217","documentation":"Thrown by ConfigPlugin._parseGroups while iterating Object.entries(groups). Each value in the groups map must itself be a plain object (isObjectOfUnknownProperties). If any group entry is null, an array, a string, or a number, this error fires.","triggerScenarios":"groups: {groupA: 'My Group'} or groups: {groupA: null} or groups: {groupA: [{...}]}. The per-group value is not a plain object, so config-plugin.js:199 throws.","commonSituations":"Writing a group as a bare title string instead of {title:'...'}. Copy-paste leaving an empty placeholder. YAML producing null for an unset group.","solutions":["Make every group value an object with at least a title: groups: {groupA: {title:'Group A'}}.","Delete the malformed group key if it is not needed."],"exampleFix":"// before\ngroups: {performance: 'Performance metrics'}\n// after\ngroups: {performance: {title: 'Performance metrics', description: 'Speed metrics'}}","handlingStrategy":"validation","validationCode":"function isPlainObject(v) { return typeof v === 'object' && v !== null && !Array.isArray(v); }\nfor (const [id, g] of Object.entries(plugin.groups || {})) {\n  if (!isPlainObject(g)) throw new TypeError(`group '${id}' must be an object`);\n}","typeGuard":"function everyGroupIsObject(groups) {\n  return Object.values(groups).every(g => typeof g === 'object' && g !== null && !Array.isArray(g));\n}","tryCatchPattern":"try { await ConfigPlugin.parsePlugin(plugin, name); }\ncatch (e) { if (/group not defined as an object/.test(e.message)) console.error('Each group must be {title,...}'); throw e; }","preventionTips":["Each group value must be an object literal with at least title.","Avoid bare strings as group values."],"tags":["config","lighthouse","plugin","validation","groups"],"backgroundTag":null,"analyzedSha":"9515cd4e58ebed69f78742d932b501c2cab8ad8f","analyzedAt":"2026-08-13T06:28:10.346Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}