pbakaus/impeccable · error · Error
config.files (non-empty string array) required
Error message
config.files (non-empty string array) required
What it means
Second validateConfig() check: cfg.files must be a non-empty array. Fires when files is missing, is present but not an array (e.g. a string or object), or is an empty array []. The live-inject flow needs at least one HTML entry point to tag, so an empty list is treated as misconfiguration, not a no-op.
Source
Thrown at plugin/skills/impeccable/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 d14711ae3d)
Solutions
- Set config.files to a non-empty array of HTML entry-point paths or globs, e.g. ["index.html", "**\/*.html"].
- Re-run the live setup flow to regenerate the config with detected entry points.
- If you genuinely want glob discovery, still wrap the pattern in an array: ["src\/**/*.html"].
- Validate with `node live-inject.mjs --check` after editing.
Example fix
// before
{ "commentSyntax": "html", "insertBefore": "</head>" }
// after
{
"files": ["index.html"],
"commentSyntax": "html",
"insertBefore": "</head>"
} Defensive patterns
Strategy: validation
Validate before calling
function hasNonEmptyFiles(cfg) {
return Array.isArray(cfg?.files) && cfg.files.length > 0;
}
if (!hasNonEmptyFiles(cfg)) {
throw new Error('config.files must be a non-empty array of paths/globs');
} Type guard
/** Narrow cfg to one with a usable files array. */
function hasFilesArray(cfg) {
return cfg != null && typeof cfg === 'object'
&& Array.isArray(cfg.files) && cfg.files.length > 0;
} Try / catch
try {
validateConfig(cfg);
} catch (err) {
if (/config\.files/.test(err.message)) {
console.error('Fix config.files: ' + err.message);
// re-run setup to detect entry points
process.exit(1);
}
throw err;
} Prevention
- Wrap even a single entry point in an array: ["index.html"].
- Re-run live setup if you remove the last entry — an empty array is not a valid no-op.
- Use globs inside the array (e.g. ["**\/*.html"]) rather than a bare pattern string.
When it happens
Trigger: config.json has no 'files' key; "files": "index.html" (string not array); "files": [] (empty); "files": {} (object). Each literal entry in files is later treated as a path or glob in resolveFiles(), so the array shape is mandatory.
Common situations: Setup wizard skipped the file-picker step; user deleted all entries thinking inject would auto-detect; mismerged config where 'files' became a single string; glob-only intent but written as a string instead of ["**\/*.html"].
Related errors
- config.json must be an object
- 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
- config.insertBefore or config.insertAfter (string) required
AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13).
Data as JSON: /api/errors/014f1f46c7f92bce.
Report an issue: GitHub.