{"record":{"id":"2cc1f072b44d29f5","repo":"pbakaus/impeccable","slug":"config-json-must-be-an-object-2cc1f0","errorCode":null,"errorMessage":"config.json must be an object","messagePattern":"config\\.json must be an object","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skill/scripts/live-inject.mjs","lineNumber":450,"sourceCode":"      re += '[^/]';\n      i += 1;\n    } 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') {","sourceCodeStart":432,"sourceCodeEnd":468,"githubUrl":"https://github.com/pbakaus/impeccable/blob/d14711ae3d1a1dd62dee61a358d27f107c51ccd0/skill/scripts/live-inject.mjs#L432-L468","documentation":"Thrown by validateConfig() in skill/scripts/live-inject.mjs when the parsed config.json is not a plain object (is null, an array, a primitive, or undefined after parse). The live-inject config must be an object so the subsequent files/exclude/insertAnchor fields can be validated; a non-object top level cannot satisfy them.","triggerScenarios":"A config.json whose top-level JSON value is an array, string, number, boolean, or null; or passing a non-object cfg programmatically to validateConfig.","commonSituations":"Editing config.json and accidentally wrapping it in an array, or leaving only a value; a generator that writes the wrong shape; JSON.parse returning null for content `null`.","solutions":["Make config.json a JSON object literal `{ ... }` at the top level.","Validate with `jq 'type' config.json` — it must print \"object\".","If building the config in code, ensure you serialize an object, not an array or scalar."],"exampleFix":"// before\n[\"src/app.tsx\"]\n// after\n{\n  \"files\": [\"src/app.tsx\"],\n  \"insertAfter\": \"</head>\"\n}","handlingStrategy":"type-guard","validationCode":"function loadConfig(filePath) {\n  const cfg = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n  if (!cfg || typeof cfg !== 'object' || Array.isArray(cfg)) {\n    throw new Error(filePath + ' must be a JSON object');\n  }\n  return cfg;\n}","typeGuard":"function isPlainObject(v) {\n  return v !== null && typeof v === 'object' && !Array.isArray(v);\n}","tryCatchPattern":null,"preventionTips":["Validate config.json with jq 'type' == object before running.","Generate configs from typed code rather than by hand."],"tags":["live-inject","config","validation","json"],"backgroundTag":null,"analyzedSha":"d14711ae3d1a1dd62dee61a358d27f107c51ccd0","analyzedAt":"2026-08-13T00:52:25.771Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}