pbakaus/impeccable · error · Error
config.json must be an object
Error message
config.json must be an object
What it means
validateConfig() in skill/scripts/live-inject.mjs guards every inject run: the parsed content of .impeccable/live/config.json must be a plain object before any other field is checked. JSON that parses to null, an array, a string, or a number fails this first check. The file drives script injection into the listed files, so a non-object root means the config was authored as the wrong kind of JSON document entirely.
Solutions
- Rewrite .impeccable/live/config.json as an object containing the required keys: files (non-empty string array), insertBefore or insertAfter (string), commentSyntax ('html'|'jsx')
- Run `node skill/scripts/live-inject.mjs --check` first to see the current content
- Delete the file and re-run the Setup/live flow — it is created once per project when missing
Example fix
// .impeccable/live/config.json — before
["src/**/*.html"]
// after
{
"files": ["src/**/*.html"],
"insertAfter": "</title>",
"commentSyntax": "html"
} Defensive patterns
Strategy: validation
Validate before calling
import fs from 'node:fs';
const raw = fs.readFileSync('.impeccable/live/config.json', 'utf-8');
const cfg = JSON.parse(raw); // throws first on broken JSON
if (!cfg || typeof cfg !== 'object' || Array.isArray(cfg)) {
throw new TypeError('live inject config root must be a JSON object');
} Type guard
const isInjectConfigObject = (cfg) => !!cfg && typeof cfg === 'object' && !Array.isArray(cfg);
Prevention
- Let the Setup flow generate .impeccable/live/config.json once; hand-edit conservatively afterwards
- Run `node skill/scripts/live-inject.mjs --check` after any manual edit — it prints existence and content
- Validate configs in CI with the same rules validateConfig() applies before shipping to the live flow
When it happens
Trigger: Running live-inject (directly or via the live flow that reads .impeccable/live/config.json) when the file's root is e.g. ["src/**/*.html"], "config", 1, or null. The `--check` flag prints whether the file exists and its content, confirming the shape.
Common situations: An agent hand-authoring the config on first live run emits the files array as the whole document; the file is truncated to a fragment by a partial write; a template placeholder string is left as the root.
Related errors
- config.commentSyntax must be 'html' or 'jsx'
- config.cspChecked, if present, must be a boolean
- config.exclude, if present, must be a string array
- config.exclude must contain only non-empty strings
- config.files must contain only non-empty strings
AI-assisted analysis of pbakaus/impeccable@f88b2837a7 (2026-08-18).
Data as JSON: /api/errors/2cc1f072b44d29f5.
Report an issue: GitHub.
Appendix: 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 f88b2837a7)