gethomepage/homepage · error · Error
Group '${groupName}' must contain an array
Error message
Group '${groupName}' must contain an array What it means
Thrown by addService when an existing group is found but the value attached to that group key is not an array. Homepage expects each group to map to a list of service entries; a group mapping to a scalar/object blocks insertion.
Source
Thrown at src/utils/mcp/homepage-mcp.js:211
const services = parseYamlConfig("services.yaml");
if (!Array.isArray(services)) {
throw new Error("services.yaml must contain a top-level array");
}
const groupName = args.group.trim();
const serviceName = args.name.trim();
const serviceConfig = args.service ?? {};
assertPlainObject(serviceConfig, "service");
let group = services.find((entry) => isPlainObject(entry) && Object.keys(entry)[0] === groupName);
if (!group) {
group = { [groupName]: [] };
services.push(group);
}
if (!Array.isArray(group[groupName])) {
throw new Error(`Group '${groupName}' must contain an array`);
}
if (group[groupName].some((entry) => isPlainObject(entry) && Object.keys(entry)[0] === serviceName)) {
return {
isError: true,
...textContent(`Service '${serviceName}' already exists in group '${groupName}'.`),
};
}
group[groupName].push({ [serviceName]: serviceConfig });
const content = dumpYamlConfig("services.yaml", services);
return textContent(
JSON.stringify({ written: "services.yaml", added: { group: groupName, service: serviceName }, content }, null, 2),
);
}
function addInfoWidget(args) {
const disabled = ensureWriteEnabled();View on GitHub (pinned to b6dca1ae03)
Solutions
- Open services.yaml and change the malformed group's value to a YAML sequence (e.g. `- Infra: []`).
- Use read_config_file / validate_config_file to inspect current shape before retrying add_service.
- Move any legitimate group-level metadata elsewhere — Homepage stores only the service list under the group key.
- Retry the add_service call once the structure is corrected.
Example fix
# before (services.yaml)
- Infra: {}
# after
- Infra:
- Grafana:
href: http://grafana:3000 Defensive patterns
Strategy: validation
Validate before calling
function findOrCreateGroup(services, groupName) {
let g = services.find((e) => isPlainObject(e) && Object.keys(e)[0] === groupName);
if (!g) { g = { [groupName]: [] }; services.push(g); }
if (!Array.isArray(g[groupName])) throw new Error(`Group '${groupName}' must contain an array`);
return g;
} Type guard
function groupHasArray(entry, groupName) {
return isPlainObject(entry) && Array.isArray(entry[groupName]);
} Prevention
- Normalize group values to [] before writing programmatically.
- Reject and report malformed groups rather than coercing them.
- Validate after every manual edit.
- Document the expected group shape for editors.
When it happens
Trigger: addService locates the group via `services.find(...)` and then checks `Array.isArray(group[groupName])`. It throws if, for example, services.yaml contains `- Infra: {}` or `- Infra: "some string"` instead of `- Infra: []`.
Common situations: Hand-edit produced `- Group: {}` or `- Group: null`; an older export wrote group metadata instead of a service list; partial migration from another dashboard format.
Related errors
- services.yaml must contain a top-level array
- group must be a non-empty string
- name must be a non-empty string
- widgets.yaml must contain a top-level array
- Unsupported config file '${file}'. Supported files: ${CONFIG
AI-assisted analysis of gethomepage/homepage@b6dca1ae03 (2026-08-13).
Data as JSON: /api/errors/2489167b15b30733.
Report an issue: GitHub.