pbakaus/impeccable · error · Error

config.exclude must contain only non-empty strings

Error message

config.exclude must contain only non-empty strings

What it means

Thrown by validateConfig() in live-inject.mjs when cfg.exclude is an array but at least one element is not a non-empty string. The check is cfg.exclude.every(f => typeof f === 'string' && f.length > 0), so empty strings, numbers, nulls, or booleans inside the array are rejected. Like the other validateConfig guards it fires before any file writes so the working tree stays clean.

Source

Thrown at skill/scripts/live-inject.mjs:462

// ---------------------------------------------------------------------------
// 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");
  }
}

// ---------------------------------------------------------------------------
// Auto-execute
// ---------------------------------------------------------------------------

const _running = process.argv[1];

View on GitHub (pinned to d14711ae3d)

Solutions

  1. Remove empty or non-string entries from 'exclude'; every element must be a non-empty string glob.
  2. If a glob was supplied as an object, unwrap it to a plain string.
  3. Re-run the injector after fixing; no files are modified on a failed validation.

Example fix

// before
"exclude": ["**/*.test.html", "", null, "**/fixtures/**"]
// after
"exclude": ["**/*.test.html", "**/fixtures/**"]
Defensive patterns

Strategy: validation

Validate before calling

const exclude = (cfg.exclude || []).filter((x) => typeof x === 'string' && x.length > 0);
if ((cfg.exclude || []).length !== exclude.length) {
  throw new Error('cfg.exclude contained empty/non-string entries');
}

Type guard

function isNonEmptyStringArray(v): v is string[] {
  return Array.isArray(v) && v.length > 0 && v.every((x) => typeof x === 'string' && x.length > 0);
}

Prevention

When it happens

Trigger: validateConfig runs on a config whose 'exclude' array contains an empty string (trailing comma in JSON-like edits), a number (e.g. a port sneaked in), null, or undefined slot. Example: "exclude": ["*.test.js", "", "*.spec.js"].

Common situations: Trailing comma produced an empty element during hand-editing; a script builds the array with a buggy push that appends undefined then JSON.stringify drops it to null; copy-paste left a blank line that became an empty string; mixing glob objects {glob:...} instead of bare strings.

Related errors


AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13). Data as JSON: /api/errors/6e7efe234df6bf5b. Report an issue: GitHub.