pbakaus/impeccable · error · Error
config.files (non-empty string array) required
Error message
config.files (non-empty string array) required
What it means
Second check in validateConfig(): cfg.files must be an Array with length > 0. A missing files key, files set to an empty array, or files given as a plain string (a common shorthand mistake) all fail here. This is the list of files the injected script block is written into, so an empty list has nothing to operate on.
Solutions
- Set files to a non-empty array of file paths/globs: "files": ["index.html", "src/**/*.html"]
- Verify with `node skill/scripts/live-inject.mjs --check` that the parsed files array is non-empty
- Ensure the array entries themselves are non-empty strings (the next validation checks that)
Example fix
// before
{ "files": [], "insertAfter": "</title>", "commentSyntax": "html" }
// after
{ "files": ["index.html", "src/**/*.html"], "insertAfter": "</title>", "commentSyntax": "html" } Defensive patterns
Strategy: validation
Validate before calling
const ok = Array.isArray(cfg.files) && cfg.files.length > 0;
if (!ok) throw new TypeError('config.files must be a non-empty array of path strings'); Type guard
const hasNonEmptyFiles = (cfg) => isInjectConfigObject(cfg) && Array.isArray(cfg.files) && cfg.files.length > 0;
Prevention
- Always author files as an array, even for a single file
- If generating the list from a search, fail loudly on zero matches instead of writing files: []
- Verify with `--check` after generating the config programmatically
When it happens
Trigger: Config omits files entirely; files: []; files: "src/**/*.html" (string instead of array) — note the inject config takes literal paths/globs as array items, not a single string.
Common situations: Converting an example from docs and dropping the brackets; an agent generating the config and leaving files empty because the project layout was unclear; glob strings written before the file list was decided.
Related errors
- config.files must contain only non-empty strings
- 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
AI-assisted analysis of pbakaus/impeccable@f88b2837a7 (2026-08-18).
Data as JSON: /api/errors/66fe8f5d11265ea6.
Report an issue: GitHub.
Appendix: source
Thrown at skill/scripts/live-inject.mjs:452
} 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') {
throw new Error("config.commentSyntax must be 'html' or 'jsx'");
}View on GitHub (pinned to f88b2837a7)