pbakaus/impeccable · error · Error
config.files must contain only non-empty strings
Error message
config.files must contain only non-empty strings
What it means
Third check in validateConfig(): every element of cfg.files must be a non-empty string. An array that exists and is non-empty but contains '' (or a non-string) fails here. Empty entries usually come from programmatic generation of the list rather than hand authoring.
Solutions
- Remove empty/null entries from the files array so every item is a non-empty string path or glob
- If the list is generated, filter it: paths.filter((p) => typeof p === 'string' && p.trim())
- Re-run with `--check` to confirm the cleaned array
Example fix
// before "files": ["index.html", ""] // after "files": ["index.html"]
Defensive patterns
Strategy: validation
Validate before calling
const ok = Array.isArray(cfg.files)
&& cfg.files.length > 0
&& cfg.files.every((f) => typeof f === 'string' && f.length > 0);
if (!ok) throw new TypeError('config.files entries must be non-empty strings'); Type guard
const hasCleanFileEntries = (cfg) => Array.isArray(cfg.files) && cfg.files.every((f) => typeof f === 'string' && f.trim() !== '');
Prevention
- Filter generated lists before writing: paths.filter((p) => typeof p === 'string' && p.trim())
- Never split a newline-joined list into an array without removing empties
- JSON.stringify drops undefined but keeps null — map missing entries explicitly instead of leaving holes
When it happens
Trigger: files: ["index.html", ""] — a trailing empty element from splitting a newline-joined list, a glob placeholder that expanded to nothing, or an undefined value serialized by JSON.stringify (which becomes null, also not a string).
Common situations: Scripts building the list via lines.split('\n') without filtering empties; agents copying a template with an unfilled placeholder; JSON written with a null entry where a path was intended.
Related errors
- config.files (non-empty string array) required
- 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/43db0c21089a673c.
Report an issue: GitHub.
Appendix: source
Thrown at skill/scripts/live-inject.mjs:455
} 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'");
}
if (cfg.cspChecked !== undefined && typeof cfg.cspChecked !== 'boolean') {
throw new Error("config.cspChecked, if present, must be a boolean");
}View on GitHub (pinned to f88b2837a7)