{"record":{"id":"66fe8f5d11265ea6","repo":"pbakaus/impeccable","slug":"config-files-non-empty-string-array-required","errorCode":null,"errorMessage":"config.files (non-empty string array) required","messagePattern":"config\\.files \\(non-empty string array\\) required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skill/scripts/live-inject.mjs","lineNumber":452,"sourceCode":"    } else if (/[.+^${}()|[\\]\\\\]/.test(c)) {\n      re += '\\\\' + c;\n      i += 1;\n    } else {\n      re += c;\n      i += 1;\n    }\n  }\n  return new RegExp('^' + re + '$');\n}\n\n// ---------------------------------------------------------------------------\n// Core operations\n// ---------------------------------------------------------------------------\n\nfunction validateConfig(cfg) {\n  if (!cfg || typeof cfg !== 'object') throw new Error('config.json must be an object');\n  if (!Array.isArray(cfg.files) || cfg.files.length === 0) {\n    throw new Error('config.files (non-empty string array) required');\n  }\n  if (!cfg.files.every((f) => typeof f === 'string' && f.length > 0)) {\n    throw new Error('config.files must contain only non-empty strings');\n  }\n  if (cfg.exclude !== undefined) {\n    if (!Array.isArray(cfg.exclude)) {\n      throw new Error('config.exclude, if present, must be a string array');\n    }\n    if (!cfg.exclude.every((f) => typeof f === 'string' && f.length > 0)) {\n      throw new Error('config.exclude must contain only non-empty strings');\n    }\n  }\n  if (typeof cfg.insertBefore !== 'string' && typeof cfg.insertAfter !== 'string') {\n    throw new Error('config.insertBefore or config.insertAfter (string) required');\n  }\n  if (cfg.commentSyntax !== 'html' && cfg.commentSyntax !== 'jsx') {\n    throw new Error(\"config.commentSyntax must be 'html' or 'jsx'\");\n  }","sourceCodeStart":434,"sourceCodeEnd":470,"githubUrl":"https://github.com/pbakaus/impeccable/blob/f88b2837a7d7c3182e46307bbbb091a1ed547571/skill/scripts/live-inject.mjs#L434-L470","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before\n{ \"files\": [], \"insertAfter\": \"</title>\", \"commentSyntax\": \"html\" }\n\n// after\n{ \"files\": [\"index.html\", \"src/**/*.html\"], \"insertAfter\": \"</title>\", \"commentSyntax\": \"html\" }","handlingStrategy":"validation","validationCode":"const ok = Array.isArray(cfg.files) && cfg.files.length > 0;\nif (!ok) throw new TypeError('config.files must be a non-empty array of path strings');","typeGuard":"const hasNonEmptyFiles = (cfg) =>\n  isInjectConfigObject(cfg) && Array.isArray(cfg.files) && cfg.files.length > 0;","tryCatchPattern":null,"preventionTips":["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"],"tags":["config","schema","files","live-inject"],"backgroundTag":"config-schema-validation","analyzedSha":"f88b2837a7d7c3182e46307bbbb091a1ed547571","analyzedAt":"2026-08-18T04:58:36.608Z","contentChangedAt":"2026-08-18T04:58:36.608Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}