gethomepage/homepage · error · Error
${name} must be an object
Error message
${name} must be an object What it means
Thrown by assertPlainObject() when a value the caller supplied (or that was read from YAML) is expected to be a plain object but is an array, primitive, null, or non-object. Used by addService/addInfoWidget/write helpers to keep YAML structure well-formed.
Source
Thrown at src/utils/mcp/homepage-mcp.js:154
error: error.message,
mark: error.mark
? {
line: error.mark.line + 1,
column: error.mark.column + 1,
snippet: error.mark.snippet,
}
: undefined,
};
}
}
function isPlainObject(value) {
return value && typeof value === "object" && !Array.isArray(value);
}
function assertPlainObject(value, name) {
if (!isPlainObject(value)) {
throw new Error(`${name} must be an object`);
}
}
function ensureWriteEnabled() {
if (!writeEnabled()) {
return {
isError: true,
...textContent("Writing is disabled. Set HOMEPAGE_MCP_ALLOW_WRITE=true to enable MCP config edits."),
};
}
return null;
}
function dumpYamlConfig(file, content) {
const dumped = yaml.dump(content, { lineWidth: -1, noRefs: true });
mkdirSync(CONF_DIR, { recursive: true });
writeFileSync(configPath(file), dumped, "utf8");
return dumped;View on GitHub (pinned to b6dca1ae03)
Solutions
- Pass a JSON object (not array, not string) for the indicated field — e.g. `"service": { "href": "..." }`.
- If the field is optional, omit it entirely so the `?? {}` default applies rather than sending null.
- Inspect the existing YAML file the tool is operating on — a malformed entry there can also trip this on read.
- Validate payload shape against the tool's input schema before sending.
Example fix
// before
{ "group": "Infra", "name": "Grafana", "service": ["http://grafana:3000"] }
// after
{ "group": "Infra", "name": "Grafana", "service": { "href": "http://grafana:3000", "description": "Dashboards" } } Defensive patterns
Strategy: type-guard
Validate before calling
function isPlainObject(v) {
return v != null && typeof v === 'object' && !Array.isArray(v);
}
// before add_service:
if (!isPlainObject(args.service)) args.service = {}; Type guard
function isPlainObject(v) {
return v != null && typeof v === 'object' && !Array.isArray(v);
} Prevention
- Send JSON objects (not arrays) for nested config fields.
- Let optional fields be omitted rather than sending null.
- Validate the request payload against the tool schema before sending.
- Inspect existing YAML files for shape drift before mutating them.
When it happens
Trigger: assertPlainObject(value, name) called with a non-object. Concrete call sites: addService passes args.service (e.g. caller sent `"service": []` or `"service": "text"`); addInfoWidget passes args.options; both also pass the parsed `name` through. The check is `!isPlainObject(value)` where isPlainObject excludes arrays and null.
Common situations: MCP client sends a JSON array where an object was expected (service config as a list of strings); client omits the field and a default isn't supplied; an existing YAML file already has the wrong shape (e.g. a service entry is a string instead of a map).
Related errors
- content must be a string
- Unsupported config file '${file}'. Supported files: ${CONFIG
- group must be a non-empty string
- name must be a non-empty string
- services.yaml must contain a top-level array
AI-assisted analysis of gethomepage/homepage@b6dca1ae03 (2026-08-13).
Data as JSON: /api/errors/2575e29722b25861.
Report an issue: GitHub.