gethomepage/homepage · error · Error
widgets.yaml must contain a top-level array
Error message
widgets.yaml must contain a top-level array
What it means
Thrown by addInfoWidget after validation passes when widgets.yaml is parsed and its top-level structure is not a YAML sequence. widgets.yaml must be a list of widget entries, so any other root shape is rejected as corruption.
Source
Thrown at src/utils/mcp/homepage-mcp.js:246
function addInfoWidget(args) {
const disabled = ensureWriteEnabled();
if (disabled) return disabled;
if (typeof args.type !== "string" || !args.type.trim()) {
throw new Error("type must be a non-empty string");
}
const validation = validateYaml("widgets.yaml", readConfig("widgets.yaml"));
if (!validation.valid) {
return {
isError: true,
...textContent(JSON.stringify(validation, null, 2)),
};
}
const widgets = parseYamlConfig("widgets.yaml");
if (!Array.isArray(widgets)) {
throw new Error("widgets.yaml must contain a top-level array");
}
const type = args.type.trim();
const options = args.options ?? {};
assertPlainObject(options, "options");
widgets.push({ [type]: options });
const content = dumpYamlConfig("widgets.yaml", widgets);
return textContent(JSON.stringify({ written: "widgets.yaml", added: { type }, content }, null, 2));
}
function listConfigFiles() {
return CONFIG_FILES.map((file) => ({
file,
exists: fileExists(file),
writable: writeEnabled(),
description: FILE_DESCRIPTIONS[file],
docs: DOC_LINKS[file],View on GitHub (pinned to b6dca1ae03)
Solutions
- Rewrite widgets.yaml so the root is a YAML sequence of single-key widget maps.
- Start from the documented skeleton if unsure: `- resources: {}`.
- Run validate_config_file on widgets.yaml before retrying.
- Make the file empty (or `[]`) rather than `{}` if you want it blank.
Example fix
# before (widgets.yaml)
resources: {}
search: {}
# after
- resources: {}
- search: {} Defensive patterns
Strategy: validation
Validate before calling
function ensureWidgetsArray(parsed) {
if (!Array.isArray(parsed)) {
throw new Error('widgets.yaml root must be a YAML sequence; refusing to proceed');
}
return parsed;
} Type guard
function isWidgetsList(parsed) {
return Array.isArray(parsed);
} Prevention
- Seed widgets.yaml from the documented template before enabling writes.
- Run validate_config_file after manual edits.
- Keep the root as a list even when empty ([]).
- Document the expected shape for editors.
When it happens
Trigger: widgets.yaml exists and parseYamlConfig returns a non-array (YAML mapping, scalar, or null for a non-empty but non-list file). Mirrors the services.yaml top-level-array check.
Common situations: Hand-edit wrote widgets as a mapping (e.g. `resources: {}` at the root); an external tool converted the list to an object; an old/partial file has invalid YAML that parses to a scalar.
Related errors
- services.yaml must contain a top-level array
- Group '${groupName}' must contain an array
- type must be a non-empty string
- Unsupported config file '${file}'. Supported files: ${CONFIG
- ${name} must be an object
AI-assisted analysis of gethomepage/homepage@b6dca1ae03 (2026-08-13).
Data as JSON: /api/errors/42ba16455ab1168d.
Report an issue: GitHub.