pbakaus/impeccable · error

config.json must be an object

Error message

config.json must be an object

What it means

First check in validateConfig() for the live-inject config.json: cfg must be a non-null object. Fires when JSON.parse succeeded but produced a primitive (string/number/boolean/null) or an array. Arrays are objects but this check uses a plain typeof === 'object' truthy test, so an array would actually pass this line and fail later — the real trigger is null, undefined, or a non-object.

Source

Thrown at plugin/skills/impeccable/scripts/live-inject.mjs:450

      re += '[^/]';
      i += 1;
    } 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') {

View on GitHub (pinned to d14711ae3d)

Solutions

  1. Make .impeccable/live/config.json a JSON object literal: { ... } with the required keys (files, commentSyntax, insertBefore/insertAfter).
  2. If generating the file programmatically, ensure you JSON.stringify an object, not a string/number.
  3. Run `node live-inject.mjs --check` to see the exact parse/validation error before attempting insert/remove.
  4. Regenerate the config by re-running the live-mode setup flow rather than hand-editing.

Example fix

// before — .impeccable/live/config.json
"src/index.html"

// after
{
  "files": ["index.html"],
  "commentSyntax": "html",
  "insertBefore": "</head>"
}
Defensive patterns

Strategy: validation

Validate before calling

function isValidInjectConfigShape(cfg) {
  return cfg !== null && typeof cfg === 'object' && !Array.isArray(cfg);
}
const cfg = JSON.parse(raw);
if (!isValidInjectConfigShape(cfg)) {
  throw new Error('config.json must be a JSON object literal');
}

Type guard

/** True for a plain object (not null, not array). */
function isPlainObject(value) {
  return value !== null && typeof value === 'object' && !Array.isArray(value);
}

Try / catch

try {
  validateConfig(cfg);
} catch (err) {
  if (/must be an object/.test(err.message)) {
    console.error('config.json is not an object literal. Regenerate via live setup.');
    process.exit(1);
  }
  throw err;
}

Prevention

When it happens

Trigger: config.json contains a bare string (e.g. '"src/index.html"'), a number, true/false, or the literal 'null'; JSON.parse of an empty file (throws, so different error) — but a file containing just 'null' parses to null and hits this. Called from injectCli() at line 141 (--check path) or line 156 (insert/remove path) after JSON.parse.

Common situations: Hand-edited config.json replaced the object with a single value; a code generator wrote a bare filename string instead of an object; merge conflict left 'null' as the resolved content; the file was overwritten by a tool that serialised a non-object. The CLI catches this and prints {ok:false, error:'config_invalid', message:...} rather than crashing.

Related errors


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