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

  1. Rewrite widgets.yaml so the root is a YAML sequence of single-key widget maps.
  2. Start from the documented skeleton if unsure: `- resources: {}`.
  3. Run validate_config_file on widgets.yaml before retrying.
  4. 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

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


AI-assisted analysis of gethomepage/homepage@b6dca1ae03 (2026-08-13). Data as JSON: /api/errors/42ba16455ab1168d. Report an issue: GitHub.