pbakaus/impeccable · error · Error
config.json must be an object
Error message
config.json must be an object
What it means
Thrown by validateConfig() in skill/scripts/live-inject.mjs when the parsed config.json is not a plain object (is null, an array, a primitive, or undefined after parse). The live-inject config must be an object so the subsequent files/exclude/insertAnchor fields can be validated; a non-object top level cannot satisfy them.
Source
Thrown at skill/scripts/live-inject.mjs:450
re += '[^/]';
i += 1;
} else if (/[.+^${}()|[\]\\]/.test(c)) {
re += '\\' + c;
i += 1;
} else {
re += c;
i += 1;
}
}
return new RegExp('^' + re + '$');
}
// ---------------------------------------------------------------------------
// Core operations
// ---------------------------------------------------------------------------
function validateConfig(cfg) {
if (!cfg || typeof cfg !== 'object') throw new Error('config.json must be an object');
if (!Array.isArray(cfg.files) || cfg.files.length === 0) {
throw new Error('config.files (non-empty string array) required');
}
if (!cfg.files.every((f) => typeof f === 'string' && f.length > 0)) {
throw new Error('config.files must contain only non-empty strings');
}
if (cfg.exclude !== undefined) {
if (!Array.isArray(cfg.exclude)) {
throw new Error('config.exclude, if present, must be a string array');
}
if (!cfg.exclude.every((f) => typeof f === 'string' && f.length > 0)) {
throw new Error('config.exclude must contain only non-empty strings');
}
}
if (typeof cfg.insertBefore !== 'string' && typeof cfg.insertAfter !== 'string') {
throw new Error('config.insertBefore or config.insertAfter (string) required');
}
if (cfg.commentSyntax !== 'html' && cfg.commentSyntax !== 'jsx') {View on GitHub (pinned to d14711ae3d)
Solutions
- Make config.json a JSON object literal `{ ... }` at the top level.
- Validate with `jq 'type' config.json` — it must print "object".
- If building the config in code, ensure you serialize an object, not an array or scalar.
Example fix
// before
["src/app.tsx"]
// after
{
"files": ["src/app.tsx"],
"insertAfter": "</head>"
} Defensive patterns
Strategy: type-guard
Validate before calling
function loadConfig(filePath) {
const cfg = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
if (!cfg || typeof cfg !== 'object' || Array.isArray(cfg)) {
throw new Error(filePath + ' must be a JSON object');
}
return cfg;
} Type guard
function isPlainObject(v) {
return v !== null && typeof v === 'object' && !Array.isArray(v);
} Prevention
- Validate config.json with jq 'type' == object before running.
- Generate configs from typed code rather than by hand.
When it happens
Trigger: A config.json whose top-level JSON value is an array, string, number, boolean, or null; or passing a non-object cfg programmatically to validateConfig.
Common situations: Editing config.json and accidentally wrapping it in an array, or leaving only a value; a generator that writes the wrong shape; JSON.parse returning null for content `null`.
Related errors
- config.json must be an object
- config.files (non-empty string array) required
- config.files must contain only non-empty strings
- config.exclude, if present, must be a string array
- config.exclude must contain only non-empty strings
AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13).
Data as JSON: /api/errors/2cc1f072b44d29f5.
Report an issue: GitHub.