pbakaus/impeccable · error · Error
config.commentSyntax must be 'html' or 'jsx'
Error message
config.commentSyntax must be 'html' or 'jsx'
What it means
validateConfig() requires cfg.commentSyntax to be exactly 'html' or 'jsx'. There is no default: the field decides whether the injected block uses <!-- --> or {/* */ *} comment syntax, so an omitted or misspelled value is rejected rather than guessed. Any other string (or non-string) fails.
Solutions
- Set "commentSyntax": "html" for HTML/Astro-ish targets or "commentSyntax": "jsx" for JSX/TSX-style comments
- Lowercase the value — the comparison is exact
- For React/Next projects use 'jsx' even in .js files that contain JSX
Example fix
// before "commentSyntax": "tsx" // after "commentSyntax": "jsx"
Defensive patterns
Strategy: validation
Validate before calling
const syntax = cfg.commentSyntax;
if (syntax !== 'html' && syntax !== 'jsx') {
throw new TypeError(`config.commentSyntax must be 'html' or 'jsx' — got ${JSON.stringify(syntax)}`);
} Type guard
const isSupportedCommentSyntax = (v) => v === 'html' || v === 'jsx';
Prevention
- The check is exact and case-sensitive: lowercase 'html' / 'jsx' only — no 'js', 'ts', 'tsx', or uppercase variants
- For React/Next/JSX-in-.js projects use 'jsx'
- Add a config lint step that whitelists the two literals
When it happens
Trigger: commentSyntax missing from the config; commentSyntax: "HTML" (case-sensitive); "js", "tsx", "ts", or "javascript" — none of the alternatives are accepted, only the literal 'html' and 'jsx'.
Common situations: JS/TS projects assuming a 'js' or 'ts' value; uppercase values from hand editing; configs generated from a form that labels the option differently.
Related errors
- 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
- config.files must contain only non-empty strings
- config.files (non-empty string array) required
AI-assisted analysis of pbakaus/impeccable@f88b2837a7 (2026-08-18).
Data as JSON: /api/errors/4c05b321b9154e69.
Report an issue: GitHub.
Appendix: source
Thrown at skill/scripts/live-inject.mjs:469
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];
if (_running?.endsWith('live-inject.mjs') || _running?.endsWith('live-inject.mjs/')) {
enterLiveRoot();
injectCli();
}
// Re-exported so long-standing importers (live.mjs, the adapter modules, the
// test suites) keep their entry points while the implementations live inView on GitHub (pinned to f88b2837a7)